{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Finished learning"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1.Search Policy\n",
    "#### BFS 广度优先\n",
    "#### DFS 深度优先"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import re\n",
    "import math\n",
    "import networkx as nx\n",
    "import matplotlib.pyplot as plt\n",
    "import random\n",
    "from collections import defaultdict\n",
    "from sklearn.datasets import load_boston"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "coordination_source = \"\"\"\n",
    "{name:'兰州', geoCoord:[103.73, 36.03]},\n",
    "{name:'嘉峪关', geoCoord:[98.17, 39.47]},\n",
    "{name:'西宁', geoCoord:[101.74, 36.56]},\n",
    "{name:'成都', geoCoord:[104.06, 30.67]},\n",
    "{name:'石家庄', geoCoord:[114.48, 38.03]},\n",
    "{name:'拉萨', geoCoord:[102.73, 25.04]},\n",
    "{name:'贵阳', geoCoord:[106.71, 26.57]},\n",
    "{name:'武汉', geoCoord:[114.31, 30.52]},\n",
    "{name:'郑州', geoCoord:[113.65, 34.76]},\n",
    "{name:'济南', geoCoord:[117, 36.65]},\n",
    "{name:'南京', geoCoord:[118.78, 32.04]},\n",
    "{name:'合肥', geoCoord:[117.27, 31.86]},\n",
    "{name:'杭州', geoCoord:[120.19, 30.26]},\n",
    "{name:'南昌', geoCoord:[115.89, 28.68]},\n",
    "{name:'福州', geoCoord:[119.3, 26.08]},\n",
    "{name:'广州', geoCoord:[113.23, 23.16]},\n",
    "{name:'长沙', geoCoord:[113, 28.21]},\n",
    "{name:'海口', geoCoord:[110.35, 20.02]},\n",
    "{name:'沈阳', geoCoord:[123.38, 41.8]},\n",
    "{name:'长春', geoCoord:[125.35, 43.88]},\n",
    "{name:'哈尔滨', geoCoord:[126.63, 45.75]},\n",
    "{name:'太原', geoCoord:[112.53, 37.87]},\n",
    "{name:'西安', geoCoord:[108.95, 34.27]},\n",
    "{name:'台湾', geoCoord:[121.30, 25.03]},\n",
    "{name:'北京', geoCoord:[116.46, 39.92]},\n",
    "{name:'上海', geoCoord:[121.48, 31.22]},\n",
    "{name:'重庆', geoCoord:[106.54, 29.59]},\n",
    "{name:'天津', geoCoord:[117.2, 39.13]},\n",
    "{name:'呼和浩特', geoCoord:[111.65, 40.82]},\n",
    "{name:'南宁', geoCoord:[108.33, 22.84]},\n",
    "{name:'西藏', geoCoord:[91.11, 29.97]},\n",
    "{name:'银川', geoCoord:[106.27, 38.47]},\n",
    "{name:'乌鲁木齐', geoCoord:[87.68, 43.77]},\n",
    "{name:'香港', geoCoord:[114.17, 22.28]},\n",
    "{name:'澳门', geoCoord:[113.54, 22.19]}\n",
    "\"\"\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Input: string -> dict"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_string = \"{name:'澳门', geoCoord:[113.54, 22.19]}\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "pattern = re.compile(r\"name:'(\\w+)',\\s+geoCoord:\\[(\\d+.\\d+),\\s(\\d+.\\d+)\\]\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('澳门', '113.54', '22.19')"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "re.findall(pattern, test_string)[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "('澳门', '113.54', '22.19')"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pattern.findall(test_string)[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "city_location = {}\n",
    "for line in coordination_source.split('\\n'):\n",
    "    city_info = pattern.findall(line)\n",
    "    \n",
    "    if not city_info: continue\n",
    "    city, long, lat = city_info[0]\n",
    "    long, lat = float(long), float(lat)\n",
    "    city_location[city] = (long, lat)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'兰州': (103.73, 36.03),\n",
       " '嘉峪关': (98.17, 39.47),\n",
       " '西宁': (101.74, 36.56),\n",
       " '成都': (104.06, 30.67),\n",
       " '石家庄': (114.48, 38.03),\n",
       " '拉萨': (102.73, 25.04),\n",
       " '贵阳': (106.71, 26.57),\n",
       " '武汉': (114.31, 30.52),\n",
       " '郑州': (113.65, 34.76),\n",
       " '济南': (117.0, 36.65),\n",
       " '南京': (118.78, 32.04),\n",
       " '合肥': (117.27, 31.86),\n",
       " '杭州': (120.19, 30.26),\n",
       " '南昌': (115.89, 28.68),\n",
       " '福州': (119.3, 26.08),\n",
       " '广州': (113.23, 23.16),\n",
       " '长沙': (113.0, 28.21),\n",
       " '海口': (110.35, 20.02),\n",
       " '沈阳': (123.38, 41.8),\n",
       " '长春': (125.35, 43.88),\n",
       " '哈尔滨': (126.63, 45.75),\n",
       " '太原': (112.53, 37.87),\n",
       " '西安': (108.95, 34.27),\n",
       " '台湾': (121.3, 25.03),\n",
       " '北京': (116.46, 39.92),\n",
       " '上海': (121.48, 31.22),\n",
       " '重庆': (106.54, 29.59),\n",
       " '天津': (117.2, 39.13),\n",
       " '呼和浩特': (111.65, 40.82),\n",
       " '南宁': (108.33, 22.84),\n",
       " '西藏': (91.11, 29.97),\n",
       " '银川': (106.27, 38.47),\n",
       " '乌鲁木齐': (87.68, 43.77),\n",
       " '香港': (114.17, 22.28),\n",
       " '澳门': (113.54, 22.19)}"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "city_location"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_distance(origin, destination):\n",
    "    \"\"\"\n",
    "    Calculate the Haversine distance.\n",
    "\n",
    "    Parameters\n",
    "    ----------\n",
    "    origin : tuple of float\n",
    "        (lat, long)\n",
    "    destination : tuple of float\n",
    "        (lat, long)\n",
    "\n",
    "    Returns\n",
    "    -------\n",
    "    distance_in_km : float\n",
    "\n",
    "    Examples\n",
    "    --------\n",
    "    >>> origin = (48.1372, 11.5756)  # Munich\n",
    "    >>> destination = (52.5186, 13.4083)  # Berlin\n",
    "    >>> round(distance(origin, destination), 1)\n",
    "    504.2\n",
    "    \"\"\"\n",
    "    #longitude latitude \n",
    "    lat1 ,lon1 = origin\n",
    "    lat2, lon2 = destination\n",
    "    radius = 6371 #km\n",
    "    \n",
    "    dlat = math.radians(lat2 - lat1)\n",
    "    dlon = math.radians(lon2 - lon1)\n",
    "    a = (math.sin(dlat / 2) * math.sin(dlat / 2) +\n",
    "         math.cos(math.radians(lat1)) * math.cos(math.radians(lat2)) *\n",
    "         math.sin(dlon / 2) * math.sin(dlon / 2))\n",
    "    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1 - a))\n",
    "    d = radius * c\n",
    "    \n",
    "    return d"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [],
   "source": [
    "def get_geo_distance(city1, city2):\n",
    "    return get_distance(city_location[city1], city_location[city2])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "727.52769688981"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "get_geo_distance('北京','上海')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "metadata": {},
   "outputs": [],
   "source": [
    "city_graph = nx.Graph()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [],
   "source": [
    "city_graph.add_nodes_from(list(city_location.keys()))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [],
   "source": [
    "plt.rcParams['font.sans-serif']=['SimHei']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAcUAAAE1CAYAAACWU/udAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4zLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvIxREBQAAIABJREFUeJzs3Xd8jWf/wPHPSU7GSYiIIMuo2FvFjlUhaDRqlNqUVlVRVEPR/KyWWjUiRR9qq1Wj9hY7SgiJEUQjUhkS2Wfdvz8S5+l5qLaKkHzfr1dezbnv677v6zrS8z3XVimKoiCEEEIILPI6A0IIIcSrQoKiEEIIkUuCohBCCJFLgqIQQgiRS4KiEEIIkUuCohBCCJFLgqIQQgiRS4KiEEIIkUuCohBCCJFLgqIQQgiRS4KiEEIIkUuCohBCCJFLgqIQQgiRS4KiEEIIkUuCohBCCJFLgqIQQgiRS4KiEEKI157BYHgu95GgKIQQ4qUIDAzkypUrTzx369YtfHx8UBTlqfc4c+YMFy5cMDv266+/Urt27b+89u9Q/+s7CCGEEH8hMjKSadOmkZaWxsyZMx87P2bMGLp27YpKpXrqfRISEhgwYADLly8nICDAdDw8PJzq1atjZWUFwKlTp7C1tf3H+VQpzyO0CiGEELlatGhBUlISsbGxbNiwgZYtW/LBBx9Qp04dfvrpJyZOnIiPj48p/ebNm+ncuTMVK1bEoEByhpZsvREbtQWOdtaUcC7G0aNHUatz6nEHDhzA1dWV9u3bc/v2bQC0Wi2HDx+mXLly+Pj4cPXqVWxsbP5x3qWmKIQQ4rmysrJi27ZtBAYGYmlpyYEDB4iKimLx4sV06tQJX19fOnXqxKhRo7h27RojR47k8uXLOLq9Qeuvt2OfmkqhIi6oLVSkhqyiTS0X1Go1aWlpfPnll0ybNg1bW1sWLlzI22+/TVxcHBkZGbi4uDBgwAD27t1rqjH+UxIUhRBCPFcWFv8drnLo0CHWrVtHmTJlqF+/PiqVilKlShEZGcn169f5/vvv+fHHH6latSoTt4YTH36c9NthFH/nc/RGBb1igVXNdqb7JiQk0LRpU44fP07lypWJiYkhLCzsueVdgqIQQojn6o/9gs2bN6dnz56UL1/+iWmXLFkCwIoVK/g1yQOjhRUqi5zQlB17lcJN3ud2tgYAOzs7Vq1axcaNG9FoNFhaWhIVFYW3tzcAmZmZAPTv35+hQ4c+U94lKAohhHiu/jhU5VEz5uDBg83SjBw5kooVKwKwdetWxo0bR9fJKzmbW8lUDDoSd83H0asDtRp+aLpOpVLRrFkz0+vy5csTEhIC5PRlLl269E8D8N8hUzKEEEI8V4qi0L59e7Zt24bBYCAhIYErV67g4+NjGgQTHx8PQHR0NJ9++imbNm3i83cbYqO2xEIFKksr3LpO4MGxVdS0vGt2/44dO3L8+PE/nZuo1+ufed6iBEUhhBDPlV6vZ+fOnXTv3h2VSoVaraZ06dJ06dKFLl26UKZMGSwtLYmNjaV169ZMnTqVBg0a4Oao4fM2lXjD2Z5aHkXo06Y+S5csYXC/nty4cQOAX375hczMTC5cuECnTp2wtLTEy8sLLy8v0tLS6N69O3Xr1uXnn39+prxL86kQQojnqlSpUlhbWxMUFATkTLjftWsXXl5eANy+fZtBgwZRokQJZs2aRYcOHQC4e/cusbev06JGWb77xDv3btUhO43ixYuTkZHBZ599xg8//EDTpk3p3bs37dq144cffqBy5cr88MMPnDhxgu+//940feOfkpqiEEKI5+rHH3/Ezc3N9Fqn09GuXTtCQ0MJDQ3Fz88PrVaLWq02BUSAnj17cuTIEQYNGmR2v759+1KkSBHWr19P1apVadq0KdevX6dp06b4+/tTuXJlAPr06UNmZibdu3d/5rzL5H0hhBCvjeTkZBwdHXnw4AGhoaG0bt3a7LzBYODw4cO0atXqme4vQVEIIYTIJc2nQgghRC4JikIIIUQuCYpCCCFELgmKQgghRC4JikIIIUQuCYpCCCFErhcWFB+tVv4iabVadDrdC3+OEEKIP9e6dWsOHjxoen3nzh38/f2fGgdOnjzJ7NmzX0b2/pF/tA7O999/T6tWrf5yBfJdu3bxySefEBwcjLW1NQDVq1fH2dn5qddNnToVo9HIhAkT/lZ+Bg4ciI+PD3369Pl7BRBCCPHc2djYmD7rdTod77//PtWrV0ej0ZjS7N69m/Xr12NpaQnAzZs3SUxM5MqVK0DOeqne3t4MHDjw5RfgD/5RUJw8eTLvvPPOU9Ns2rSJefPmMWbMGG7evMmDBw8IDg7m8uXLf3l/a2tr0xv2v7RaLfXr18fBwYGsrCw0Gg0JCQmEhIQQHBwMgKWlJampqVy4cOGfFEsIIcRz8tFHH1G8eHHTuqePNGrUiGrVqpm2kpowYQIfffQRzZs3B8BoNJoCa176R0HR2dmZdu3amV5fuXKF6OhoXF1dSU9PZ+LEiXz33XfUq1ePdevWARAXF4eiKPj5+WFhYWGqYiuKgtFoNAuCKpXKbMdmRVHIzMzEzs4Oa2trU7CbOHEiaWlpzJ49G71eT61atZg5c6ZZ3oQQQrxcw4YNIyIigoMHD+bsgpGcSfCRKMJikqnl4ci5/0xAn5WBSqXi6NGj3Llzh2XLlgE5FZ/g4OC/bFF80f7VMm/Ozs7Ex8ejUqk4efIkJ0+e5KeffmLQoEEUK1aMPXv2oNVqTQu+Dhw4kIs3fiP4SBQhZ89z4YcvKe1anCKFC5GcnExkZCQADRo0wGg08uDBA7Kzs01bhjyi0+lo37499evXJyYmBnt7+8e+lQghhHhxjEYjiqJgaWmJn58fAQEBXLp0ia5du+Ls7Exscibt5h0jLTMbvQJqjBSy07BrWFMifz3J4sWLTZUnyKkEabVabGxs8rBUzxAUFUVhwoQJRERE8ODBA7POVcgJaN27d6do0aIcOnQInU5HmzZtABg1+nM8hq0mPVuP3qigtlBhb6Nm17CmjBvxMSdOnOC3335jzZo1vPvuu3+ah/j4eDZs2MDIkSMB+Prrr2ndujWenp5mbdhCCCFejCNHjtC/f3+sra2JiYmhWLFi2NjYcOvWLTw9PUlIy+Zhph6jQUeJd8eRtP97LK1tcbTUkfTbdVOzaXh4OPb29pQpUwatVsvWrVspUqRInpXrmWqKP//8MzY2NrRs2RJbW1uzcwMHDnysZvfInQdZWPhNRG/87yOtLFS0cTey/ZshDBo0iDt37vDrr79y+vRps/2wbt++Tbdu3UhOTsbd3Z02bdrQq1cvsrKyWL16Nfv27SM8PBy9Xs/Zs2epUqXKPy2WEEKIZ/Copujt7U2NGjX46aefCDiYSFhMilm6zNsXSN0znxGDB9C4cWMArl69ytdff80333xDjx49sLOzy4simPyjoFi7du3Hjun1elQqFUuXLmXJkiUUKVIElUr1xOt/Pn+X35NTsS1dE/vKTQBQjAbSN09k6uiPSU1NRa1Wc+bMGTw9PZk8ebLZ9REREVSqVIljx47x1VdfcfjwYQACAwNxdnZm6NChxMXF4eLi8neLJIQQ4l/6Y1BctWoVP/zwA00+ncu6c3fRGxX0D+NJ2PYtNsXLwG/n+XHJIrMK1dixY/H09CQkJIQ9e/ZQq1atPCvLPxpo86RRnWfOnGHUqFE0aNCABg0a8M0337B79+4nXm+ncqBk2yFmNcWUA0so6VSUDz/8kFmzZgEwf/58GjZsiEajYdy4caa0j2p/iYmJVKpUyXTc0tLSVKuUgCiEEHljx44dlCtXjsKFCxOx7hs0lXuSiQU4FMet60QKOxYlfdWnzJgxw2xQ5a1bt1i7di1ly5Z9rPXxZftHQdHb29v0u1arpWvXrpQqVcps3uKtW7fw9fWlRo0aZtfqdDrGT/wKexs16dl6tNlZJO9bhD4hmh2nj5vVLosVK8ahQ4fw9fVl//79LFq0yCwIbt261dRPCfxpzVQIIcSLp9Vq+eKLL4iOjub7779n7dq1dO7cGd2GL6j77kdkutWmdukyDG7uyVtrVOzdu5dChQqZrvfx8QHI84AI/zAohoSEPHasZ8+eZsESclazSUtLMzum0+mwsrRg57CmBB+J4sT5y8QXs2PdtiNU8Cj+2H09PDw4deoUs2bNws3NDYCHDx8SGBjItWvX+OGHH0xpZZ9kIYTIG0ajkcjISHx9fdmzZ48p2O3atYugoCBu377NjKGfmiovlpaWtGnTxqymGB4eTnZ2dp7k/3/9o6D4R2vWrOGTTz6hXr169OjRw3Q8JSWF06dPc/ToUbP0RqMRrVaLm6OGSf7Vwb860M0sjVarxWg0ml4XLlyYwMBA0+sPPvgAV1dXDhw4YDYIJzs7+5V5Q4UQoiCxsLDg1KlTpsrLIyqVik8++eSx9H9nIZe89MzzFB+tO2pvb292PCsrCysrqz9dmUYIIYR4Vf2ryftCCCFEfiJbRwkhhBC5JCgKIYQQuSQoCiGEELkkKAohhBC5JCgKIYQQuSQoCiGEELkkKAohhBC5JCgKIUQBceXKFUJDQ82OabVaihYtSlJSUh7l6tUiQVEIIQqI6Oho2rdvz8qVK03H1Go1Wq0WJycns7QVKlTA29ubWrVqUadOHX755RdKlCiBl5eX6cfDw+NlF+GFe+a1T4UQQrxe2rVrx549e7h79y6ffvopJ0+eBHLWj/by8jKl27RpE1ZWVhw+fJglS5aQkpKCtbU17du3Z/ny5UDOXrqenp55UYwXSmqKQghRANy/f5/Q0FDq1KmDn58f0dHRzJw5kyNHjlCyZElCQ0PZtv8YMYlpfLD8NAnpOmKTM9m0aRMdO3Z84hZ9+XHbPgmKQghRAPz666+0atWK8ePHm3YjsrCw4Pfff6dEiRLEJmfSbt4x0myciYhLJTlDR7sZu7h85QqVK1fO49y/PNJ8KoQQBUDbtm05cOAAc+fORaVSsW3bNgB27txJRkYGI2f+h3TlDZzfHZt7hUK2hS22zqXZvn07Go2GHTt2mDWz5kdSUxRCiALCy8uLWbNmsWHDBtOxkJAQChUqxNnjR9AbzTdN0ilQtsMQZs6cCYCfnx+hoaGEhoZy6tSpl5r3l0WCohBCFCA//PADP/30EwAGg4HVq1fj5+dHiSJ2qC3M+witLFQ0rFWVq1ev5kVW84Q0nwohRAGRlZXFggUL+OWXXwBYvHgxZcuWpV69evyelMJJGzWpaekYLa1RoUKJi2RdwAhatWqVxzl/eSQoCiFEATF79myqVq1KnTp1iIyMZPz48Rw+fJjo6GhsLBR2DWtKl/6f8FBlh4OtJdu/6ok2uTW1a9dm37597Nq1C29vb9P98uMe9dJ8KkQBpdPpiI6O5siRI3z33XcsWrTosTRZWVmcPn36qfcJCgoiJiYGgKSkJFatWgWARqNBq9U+8Zpjx47h5+dndmz+/PlMmjTpWYoi/oaHDx+yePFihgwZwu3bt2nTpg0TJkygRo0alCtXjrVr1+LbtD43ju9gTeCHOFhDRY8S1K5dG8iZ5N+vXz9CQkIICQnhyJEjpnP5idQUhcjndu7cycSJEwEoW7YsvXv3Zvjw4RQqVIj4+Hhq1KhBgwYNcHd3R1EU5s+fz/79+7l58ybZ2dlUqVKFjRs3Ym1t/di9jUYjERERTJw4kY0bN5Kamsry5cvp1asXVlZWWFlZPTFPtra2ODg4ADmTwC0sLLCzsyMtLQ1FUcjKykKj0by4N6UAcnBw4MqVK6Z/l2XLlpmaRatWrcr9+/fN0kdFRZm9btmyJS1btjS9trS0ZOvWrS8+4y+bIoTI19auXasMHz5cuXXrllK9enVFURTlzp07iqIoSt++fZUtW7YoGRkZyrlz5xRFUZSoqCjl6tWrSv/+/ZVDhw4piqIoRqNRKVeunFKrVi2lVq1ayhtvvKFkZWWZnrF+/Xrl9u3bSu/evZVSpUopTZo0UdRqtdK4cWOlfv36ymeffWZK26pVK+XEiRNKz549FUVRlE2bNil16tRRypYtq7i7uyt169ZVWrVq9TLeGiEeIzVFIfI5S0tLs99TUlJo1KgRt2/fNh3fsWMH69evZ8OGDZQuXRq1Wm2qGer1etO1Fy5cAMDV3Z0pO69y4bckPAsZGNOpA7bGTLZt28bNmzdxcnLCw8OD48ePm+Xl5s2bhIWFMX/+fH799VcmTJjA5MmT6dSpE8uXLycuLo6AgIAX/I4I8eckKApRwBQpUgRvb28iIyNNxw4ePMjw4cOJi4vj3XffRa1Wc/78eY4fP46dnR0jR47EwiJnCEJsciaJaVrWhsaQeiOUndtmsHHLB5xYNoWLFy8+trA05PRfPnrOmDFjaNmyJXPnzmXSpEl069aNa9euYTAYUBSF2bNn4+rqSt++fRk5cuTLeVOEyCVBUYh87n/Xp7x8+TI9e/YkJiaGu3fvcv78efz9/Xn48CGJiYmcOnWK33//ndKlSzNmzBgaN26Mp6cnX331FQDBR6IwKgp6o4KmXF1KdA0k+951Pp30HXGnt5v6EcuWLWsaqajVaunXrx/t27fH2tqa2NhYFEXh3LlzrF+/3ix/lStXJiws7CW8M0I8ToKiEPmc0Whk9erV7N27FysrK2JjY7lw4QJWVlYkJSVx69YtNBoNOp0OtVpN9erVmThxIoUKFSIiIoLp06dz5swZ0/3CYpLN7m/tWhHLQsWgUgVOzxv/1LwoisKvv/5KUFAQO3fupFSpUmzevJmdO3ea0ty+fZuaNWvyxRdf0LNnz+f7ZgjxFyQoCpHP6fV6evbsyYgRI3j77bdp3bo1rVu3BiAyMpKOHTvSsWNHU/r9+/cTFhZG586dadOmDWlpaWZBq5aHI7/84f5Zd8JJPriUWr7bOHr0KP7+/mZbCt2+fZsZM2YwYMAAjh07xoQJE2jZsiVvv/0233zzDVqtlu7du1OzZk0gp6Z44cIF06LVQrxMMk9RiHwuKysLgJIlSxIcHPzUtFevXmXgwIGsWLHC1Ic4d+5cunTpwr179/Dy8mJrYB+MGSmmJcGyr5/EsUpjBjf3xMbGhubNm5vWxwwNDcXPz8/UpNqsWTOOHDliNkdRrVbz/vvvmy0lZmFhgVqdN9/ZExIS8uS54tUgNUUh8rmuXbvSsWNHNBoNTZs2NTun1WrN5hKWKVOGNWvWULFiRdOxR8HR2dmZ0NBQIGf0afe6bvx683cORhzhp917cXPU8Btw5MgRs50Ubt++jY+Pj9lzFUUxrYZiYWHBvHnzUKlU6PX6PK8hdunShVGjRtGhQ4c8zYfIGxIUhcjnChcu/NixjIwM6tevz4MHD/j2229Nx21tbWncuDGQU8PMzs42ndu7d6/p96sRETg4OHDjxg0+P96KNk0bAjlBtnnz5vz888+mtP369XtsZZvs7Gyze7dq1Yrr169TvHhxBgwY8C9LbK5kyZLExMQQGhrK1KlT2bFjh+ncrVu3mDRpEtbW1qYBSQaDgWHDhpnWB4WcJujRo0cXqH0FCyqVouTDxeuEEH8pIiKC8uXL/+mqM89Cq9WSkZGBo6PjM12vKMpz383dw8PDFBSnTJliFrDT0tK4cOECNjY2T32uXq+nSpUqFClS5LnmTbx6pKYoRAFVpUqV535Pa2vrJy4H93c9r4Co1Wqfmo+tuw8yYsw4Kvf+inoVS+GRfJGgOTOemLZv37589tlnzyVf4tUnQVEIke907tyZ2NhYVCqV2ZqesbGx+HfqysGLNynSpAcRSUaun7lD9uVz+DbyZumiBWb3WbBgAffu3XvZ2Rd5SIJiPnflyhUyMjJMr4OCgihZsiSdO3cGcuawFSpUiKpVqwI5fTvz5s2jWrVq6PV62rZty/z58/Hw8KBDhw4sW7aMN954w+wZj5b1etRkdvHiRUqWLEnJkiVfUimFMLd9+3bT7x4eHqbfk5OTqdZ5GCWrOJl2mdcbFbJ1ei7FpDzxXs+7OVe82iQo5nNhYWHcvXvX9DomJoa0tDQOHz4M5ATF0qVLm4Kira2tqdnpvffeo0GDBnh6emJtbU3fvn1p1qwZ4eHhZn0ra9as4fz582zatAmA8ePH06hRI8aOHfuSSinE31O1alWSCpVFn2weAA1GI2Ehu6hduzZGoxGj0YharSY5OZkePXrkUW5FXpCgmM/Vrl2b+fPnmwLd7du3sbGxMTUpabVali9fTlhYGElJSahUKpKTk/n2u4U4NelGuK07Df164NuwJl9PmkiLFi1MAdFgMGA0GhkzZgy9evUiOTmZ9PR0IiIi2LhxIzqdDpVKlWfzzYR4kloejlyOfWiqKQI4vdkOL3d71s8MYP/+/ezevZugoCB2797NO++8k4e5FS+bfFrlc1WqVKFXr16P7ZX2SPny5alYsSJr16417Z92Oy6RwNmLcO01g6zkG8SdPEzEpfMM/Hgonn9oOj106BDDhg0zBdzKlStjbW2Nk5MT9evXx2g0Mm7cOLp37/7iCyrEHxgMBsLCwjhw4AAPHjwwO/dRs3JsORfNw5R4sHfCWq3m4fE1xKdfAwJMi5fHx8fz2WefsX37doKCgkyjdFeuXMnVq1eZMmXKyy6WeAkkKBYAQUFBLFiwgEKFCpkdv3fvHgsXLjRtCPuoRvdL+H2MWKA3KiTtDaZIk26odFm079iZsCO7sLW1BcDHx4crV66Y7jd+/HjKly9Pv379XlrZhPhfV65coWnTpnh7e9OuXTvT36tarebOnTs8uHuTuOD+JKc8BAtLjDotKhTUJUtSrVo1Hj58SOfOnXF3d6d3797MnDmTiIgIXFxcuHfvHklJSWRmZhISEkJ2djZz5syhYcOGeVxq8bxIUCwA6tWrx4gRIx6bO5aYmEi7du0eS38jPmf385STGzBmp1OodltAReaRRTRs2JDFixdTv379v3yuoihotVpsbGyeV1GE+EtVq1blxo0bFC1aFIAvv/wSrVZL1apVKV++PL1798bdzY2GDRqwevVq+vTpQ5MmTfj8888ZPXo0q1evpkmTJgAEBgbi5OSEg4OD6cveunXriIyMJDAwkMGDB5OZmZlXRRUvgEzez8fu3r1LZGQklpaWfPLJJwwZMoRq1aoB8Ouvv7JixQrmzp2L0Wjk3LlzGAwGQkJCcG7yHusWfg2W1ij6bFQWlqiAYvZqWjWozdChQ6lXrx4dOnQgJSXFtAxYZGQkOp3ONDpVURSys7MJCwsz2+hWiFdJYGAgjo6OjBgxgri4OKysrMi2tGPB/ggOHTpE6za+pB5fTcih/djY2JCQkEBGRgalS5cmKioKBwcHZsyYgb+/f14XRTwHUlPMx7RaLcnJyaYVRtzd3UlOTkav1+Pm5kZAQABxcXFYWFiQnZ1taj7tWNudjVbWuPT4mujgDyk7eDF2NmoqRa7k448/pl69eoD5sPe0tDSqVKmCnZ0da9eupUKFCnlSZiH+SpkyZdDr9aapFg8fPsTCwoKZM2cCOSNR41MycOs9g3sb5hB+ZAdl3x3F7r0TcC9q91hNsVu3bjRv3jwviySeI6kp5nO9evUiLCyM+Ph4ypYtS7ly5XBwcODSpUsULVqUuLg43n//fVxcXJg9ezZJSUlUqFCBlNR0fAO+Z85Hb/PZ978wuLkn40Z8zODBgx/rP9HpdHTu3Jn69evj5eXFoEGDWLt2rWmDWSFeJY8WQX8UFOvUqQPA+fPnAZjw8yVWn4zCaGGFUZtJxvVTFK3xFhb7Z+JIOsnJyWRmZlK6dGkePnzIwoULH1toXby+ZOuofG7VqlXUqFGDHTt2sH79etRqNTY2NkyfPp0dO3YQEBCAtbU1bdq0YfPmzURFRbFu3Trq1qnFJP/quDtq2Dm5H+/4NGXHjh388TuUoijs27ePevXqUatWLcaPH0/btm1ZuHAhfn5+dOzYkQ0bNpi2LhLiVfDHxb9Pnz6NRqOhbNmybNmyBYCLd1MwWuSMNLWw1qBPjCEj6R5F67Zj8uTJdO3alRYtWhAYGMjMmTOfuOC6eH1J82k+9/nnn1O/fn1cXFyYNGkStWvX5saNGwwZMgQHBwcSExMZOHAgxYsXN13j5OREUFAQkLNTQmRkJJCz28Efdzbo1KkTKSkpBAcHm9Ue33nnHa5cucKkSZOYM2dOvu5rWbJkCbVr1zY1KYvXh1arZejQoXz++efUqFEDHx+fnC94f5jHqL1/m4yrJ3Cq3xFXVbxpLm5WVhbJyckYDIbHRnWL15s0n+ZzCQkJODs7oygKOp3uXy3W/L+ysrJMw90Lot9//526dety+vRp3N3duXPnDtWrV6dcuXJATj+rt7c3y5cvB2DkyJHY29szefJkLl68yKxZs/jxxx8BePvttxkxYgStW7fOq+IUKAkJCfTs2ZMSJUqwcuVKAJYuXcr06dMJ+s8qRh9KIT1bz911EylSvSWG+JuU1sdQ2E7D/fv3ycjIoGzZsiiKwsOHD9m3bx/Ozs55XCrxPEhNMZ979D+qSqV6rgERKNABEWDChAnY29vzzjvvkJaWxsGDB6lWrRpz5swBckb4XrhwwZTeysoKJycnIGcroujoaLNzz3MLJ/Fk6enprF69mgkTJtClSxfTvxXAwIEDsbCwoJt/O1q2bkuCRVHupcQysG8vhrxVETdHDZDTJXH16lUmT56cV8UQL5AERSGewU8//cSVK1cIDw/HysoKg8HAgwcPuH//vmkT2+joaFDbMHFrOGExySRGJdHe2QX472724uW6evUqa9asYe3atbz11luPnR8wYACtWrUiKCiI/4wbx40bA6hbt5ZZGp1O99imySL/kKAoxDNo2rQphQoVokqVKhgMBrp06cIXX3xB8eLFadu2LQCHT5xhzvp9FHW7g96okPxbIrezb9FvUP6b7J2cnIyDg8MLD/b/dhPiN99807QY/p8pU6YM06dPB6Bu3bqPne/fv/8zP1+8+iQoCvEMXF1dcXV15f79+8TFxREQEEBCQgK///47gYGBKIpCRuFSWLpVMS08bdBr0amsCD4SRacyeVyA56xdu3b07NmToUOHPjWdTqfDwsLiscUc9Hq9aZ6sTqdDrVY/FvxGjBiBi4sLAQEBfytPcXFx7N27lz59+vyDkoii0pdFAAAgAElEQVSCToKiEM+oXr163LlzB4PBwHfffceePXuoVKkSkyZNYu7cuVy38yTllxVoqrZAZWGJIS0JNEUIi0mmU5n8N2KxVKlSTzx+/fp1atWqRdWqVbl79y4pKf/dtikzMxM7Ozusra3x9PQEcgZw7dmzhy+++MLsPhEREdy/f5/w8HDTMWtra/7zn/888bkqlYoPPvgAPz8/nJycMBgM6HS6At8XLp5OgqIQz+js2bMsX77crKYI4OXlRXh4OBlWd3Dt9n9gYZmzDuy962h8BlHLwxHQ523mn7OsrCzs7e2feM7KyoqKFSsSGhoK5NQEK1euzMyZM5kzZw5Hjx597JqkpCSOHDnCyZMnTcfiUjJZdSqaK/ceUtXVgV4Ny9CqsZcpKMbExFCuXDnT6F8AT09PGjduDOTURnU6HREREdjZ2T23sov8RYKiEP+S0Wjk+++/p3PnzkBOv1dAQADLV64mztGJDJ2R1OuhWNrYUaSkO4ObexJ3MyKPc/3s0tPT8fT0pHDhwqZm0Fu3btGvXz/TnD2tVourqyvHjx83u87NzY0aNWrg7OzMwIEDKVKkCE5OTpw9e9ZUU4ScrZ9cXFzw8PCgevXq2NoV4kpMIkaVBVioOaLP5hf/z3irdVuzvHl4eJjm1QJs2LCBtLQ06QcUf5sMgRPiX7h//z7ffvst0dHRpKamEhsbi7e3Ny1btqSYowNOx2bRwimV9CM/4NO1L7uGNcXNUUN2drbZQghGo5HXZcqwvb09cXFxXL9+ncjISMLDw7GwsODNN98kMjKSyMhIbt68yYZf9jNxaziDVpwlLiWLxEwjtra2BAQE0KlTJzIyMpg2bRqOjo6P9TEWL16cs2fPAhAaGop9uTcxGAwU7/IVLr1m4NJ3DmnxsdToPcHsuv8d6HP79m3u3LnzYt8Qka9IUBTiX0hLS2Pq1KlMmzaNW7duYTQaCQoKwtXVlR9//JEaVSvTp54rA9/vxLb5X5nmujVq1MisafB/g+Tr5NixYzRt2pTLly8TExMDQGxyJu3mHWPNmTtE3EvlQaYev/khGIwK9+/fZ9asWVhZWREQEMDdu3dp3749tWvXplixYqxcuRKdTsehQ4cYNWoUdevWJT7TiCErDV18NEZdNok75vAgdAdnIm6Z8mE0GrG2tmbv3r14enpSuXJlvv32WxYsWEDlypWpVKkSgYGBefQuideFrGgjxHOUnZ1d4PaP9PPzY+jQoURERHD48GG2bt3KxK3hrDmTMxVF+/tNkvYvxr3b/xE9tzsaWxuysrJwcnKiVKlSXLlyhfPnz1OpUiUGDhyIj48P7du3p2vXrvj7+9OuXTv8+w/jVmI6mXcuY6kpjFGXRZmPvqdHgzJM8q8O5AzE6d27N6dPn8ZgMGBtbc3MmTPJyspi/Pjx6PV6DAZDgfv3Ef+M1BSFeI4K2gducHAwiqLg6+vLsGHDuHv3LrNnzyYsJtk0FUX3IBa1Q3Eyk+5hU8SZHj160KtXL9zc3Dh+/DhJSUlUqlTJdE9LS0scHBz4+uuvuXr1Ku+99x7jRgymkKsnxqxUHBp1xdrRBeKvM7j5f/shExISeOONN7C0tHzi6k2PFsMX4mkkKAohnsncuXOZN28eDx8+ZNeuXVhaWrJ161aCgoJ4cHQVlhgByLp9AZtS1bCyscHGSk2XLl1MfX/bt2+ndevWJCcnm+6rUqlITk5mwoQJ1KxZkwULFrBs0TwGNS1Hy24f4mKZwXsfjsBwcAHJsf9tPg0PD6dq1aov900Q+Y4ERSHEP3Lz5k06derE5s2bOXbsGPPnz+eDDz4gLCwMd3d3Dh06RPadS9xdOgTD7zfIuHaSQqWqkbjzOwZ9MIC6deuSmJhIZGQkU6ZM4ebNm7i7u1OrVi22bNmC0WhEo9HQv39/Nm3axOTJk1mwYAETAkbjakxgmG91ln3Ri/HjxlK/fn2OHTsGwL59+6hTp85Tl2DTarUYjcaX9VaJ15EihBD/QHR0tLJgwQJFr9ebjp08eVJJSUkxvTYYDMriH9co/b9ZqVRo00sZvzlMWbNpm6IoirJu3TrF1dVV8ff3N6WPiopSFEVRPvjgA2XlypVKXFyc0rVrV+Xo0aOKoihKXFycYmdnp7z33ntKenq66brIyEjTf0uUKKFs3LhRcXZ2Vtzc3BR3d/fHfpydnZWTJ0++uDdHvPZkoI0Q4qXLyMjAYDD8ow16n7ZV2fXr1zl//jzvvffe88qiKKAkKAohxN+QkpKClZWVrIaTz0mfonjtTZs2jSNHjuR1NsRrIC0t7bFFEi5dusSWLVv+8toVK1bw+eefv6isiVeE1BRFnrt79y6+vr6mZcPu37+PRqPBysqKpKQk3NzcgJwmt40bN5qtbQk5H1Z79+5l1apVeZF98RpZvHgxP//8M8uWLaNYsWKo1Wpu376Nj48PERERpr0xQ0NDGTRoEMWKFTOt6RoZGYlGo6FMmZwtThRFITU1lblz5/Lmm2/mZbHEcyRBUbxyAgMD8fLywsXFhaVLlxIcHGw6l52dja2tLeXLl39sabA/unnzJuHh4VSsWPFlZFm8RlavXk1UVBT37t3jxx9/NAW0zMxMIiMjqVmzJosWLaJ27dpm17Vr146JEyfSqFGjvMi2eElkQXDxWnk0v+3kyZM4Ozv/abq/Cpqi4ElMTOTbb79lzJgxODk5AVClShV0Oh0jRoygV69eDBr6GbFOtfnqeDLh/RpTzBas1Tl/c+fPn2f48OFmCwNUr17d7EubeP1JUBSvhFu3blGzZk0qVapEbGwsa9asQa1Wk5CQQGhoKDdv3abzl0H8bu3KoNkbSFes+fOQCMuWLcPFxeWl5V+8+ooWLYqHhwcNGzbkxIkTODs7M2zYMIYOHUq1atXw79KdRb+VIP1GzvJ0v12/gs2QYH4a3IR92zYSEhIC5Cxa0K9fPyIjI/nyyy/zuFTieZOBNuKVYGNjQ926dQkNDaVjx46sWbOGFStW0KlTJ7btPwal32R3RAIX7z7kx69HU6VWXWrVeRMvLy/KlSuHs7MzXl5eeHl5UbduXYYMGUJCQgKTJ082m6ydmppK7969efDgQR6WVuQFCwsLhg4dysWLFzEajSxbtoxevXrx4MEDvvnmG7YeCOH68gASjq5Bl3QXCytbMrV61l9KZv/+/URHR7N9+3Z27dpl2iJLo9HkcanE8yZBUbwSHjWLKorC6dOnqVatmulc8JEo9AYjhtzub9cPFuLe/zv8A1cQGhrKpEmT8PPzIzQ0lNDQUM6dO8elS5dwd3fn7NmzDB482HSvhQsXkpycTNGiRc2eryiK2c7xFSpUICMjA4CpU6cyY8aMF1Z28XItXryYrVu3cufOHezs7Khbty4dO3bE0qUSaucyWNo7YmlXBFQW6I2wYEQ3kpKS6NmzJwMGDCA6OppWrVrldTHECyJBUbxS5s2bh7e3NxqNBgcHB7Zv387iLz9En5lmlk5nVAiLSf6Tu+RQq9WsXbsWtVpNamoq8fHxLFmyhKVLlz6WVqVSmS0WbWNjY+o7+uPv4vWWnZ1NcHAw/v7+fPXVV5QqVcr0BcnDqRDWhZ0oXKcdFrY5NUFLRc/AKUs4fvw4fn5+jBo1isjISHbt2iXLxeVT0qcoXinFixdn0KBBAFSsWJGdO3cy55cLbFq30iydlYWKWh6Of3qfMWPGsHnzZtTqnD/xevXqkZGRQVZWFs2bN8dgMODr68uCBQvYsWMHnp6eqNVqdu/eTbNmzYCcVVIcHBxeUElFXpgzZw6dOnWiRIkSQM4cRV9fXwAal3fmUkwSagtV7g4fCsbYy+yaMYdDc62Ii4sDYOPGjRgMBnr27JlXxRAvkARF8UpQFIXz588TFBREUFCQ2Tmt3kjWzQgcG3QCcgKinY3abNug/zVjxoynNnnGJmcSfCQK/4UhRPw4i28n5ezgvmfPHjIzMwG4cOECJ0+epHTp0v+2eOIVcP36db777juuXLkCwK5du4iKiqJevXoAFNFYMdC7HNQsTVhMMokqPdu+HkLtSt8C8PXXX6NSqQgICADg1KlTHD58OE/KIl4cCYrilZCdnU2dOnX+9EPmvR69cahcjHjbItTycGRwc0/cHDUMGTKEdevWMWrUqL/9rEe7wqdn69EbFWKjrvHlkZz9/7p06cLChQsB6Ny5M9OmTcPf3/+p0z/E66F8+fLs2rWLokWLkpCQwLfffsvmzZtRqVRAzg4atpYK43I3LXYYm41Lkf8OpClatKgp7aVLlxg7dixvvfXWyy+IeKFk8r54JSiKQlZW1j8ezXf//n3UarVp3tkfubu7Y2dn99h8xfjUbB6mpeM+ZBlGXTb310/Eo8dUUtaOIu7WVXbu3MnYsWO5cOECx44dY//+/RQvXpwRI0b8qzKK/EVRFFOQFPmHBEVR4PgvDCEsJsXsmC7xN7RHfyA+8iyQMyn7woULqNVqZs6ciVqtlqAoRAEgo09FgVPLwxG1hfk3/KxrJ6j2Zv08ypEQ4lUhQVHkO4qioNPp/vT84Oae2NuoscSIohixyHrIw3M7+Hbcf2uCer0eg8HwMrIrhHiFyEAbke/cvHmTNm3aoFar/7TPR2cwkpiSTo0+E9HeOIbfhwOpV72C6fzUqVNNCwpkZWXJPEUhCgjpUxQFnsFgwGg0YmVllddZEULkMQmKQgghRC7pUxRCCCFySVAUQrxwRqORY8eOATl9vsuXL8/bDAnxJyQoCiFeuKysLN5//31u3LjBhg0bCAsLA6Bx48aUL1+e2rVro1KpTEuwya4lIq/I6FMhxAtnYWFBUFAQhQoVYsuWLaxYsQKDwYC1tTVLly6lWLFi9OrVi6pVqwJ/vWvJo4XehXje5C9LCPHC+fr6otPpuHz5Mm+88QZ9+vQhICDAFNxWrd+Ec62W+C8MQXMvjI87NJZdS0SekKAohHjhjhw5AkCLFi2YO3cutWvXBmDBggUkpGUzf9kaincMQBWTQvymFYTGacGoyK4l4qWTPkUhCoBPP/2U2NjYPHn2li1b8PLyonHjxpw/f57+/ftTv35901qy2y7EYlWyAg+v5AzE0SbEYCziTnKGli5durBhwwYgZ9eSQ4cOkZz89M2lhfg3pKYoxGvg7t27+Pr6UrhwYSwtLbl//z4ajQYrKyuSkpJwc3MDICMjg40bN1KuXDmz6ytVqsTs2bOZOXPmS8/7u+++y7vvvgvkbCK9Z88e0ya/Pj4+RMWnUaTlAO4tG4bGsx6W9kUxWFijNUDDhg1JSkri4sWLWFhYMG/ePPbv3//SyyAKDgmKQrwG3N3dCQ8PN70ODAzEy8sLFxcXli5dSnBwsFn64OBgJk6c+FhTo5eXFwD37t3jk08+Ydy4cS8+87mOHz+OtbU1fn5+bNiwgTJlygDgWbwQv2dqsKvsTXrEUVx6TUdJisG5pAuWlpZ06NCBsWPHAtCyZUvOnTv30vIsCh4JikLkE7HJmQQfiSIsJhklMp63/TuxbEkwN2/eZPLkyfznP/8xrQU7ZcqUx/aZfJGys7MZPnw4QUFB2NjY0Lx5c7Zs2QLAO7Xd2PPtCjKuHMaxRT+sLFSk3jhJ7/Y+Ly1/QjwiQVGI18StW7eoWbMmlSpVIjY2ljVr1qBWq0lISODk6TNcvhaFa/fJWJbwRGVdCY2mIrHJmcybN49atWqZLY7eu3fvl5bvBw8e0KdPH6pUqYK/vz8As2bNwsbGBr1ej3MhG4a0rU1Uax9SilaggoPCiqW7GLY81HSPR7uWyFQM8aLJX5gQrwkbGxvq1q3L4cOHGTJkCAMGDABg6dKllGg3lFsTRmBQWWJhNBC7KgBLa1vqb5tGYvQ1atasycaNGwFIT0/H3t6ezMxMFi1aRP36L3YfyczMTGrWrMn//d//mY517twZwLTF11djPzedGz58OIMGDjSbvC+7loiXRRYEF+I1ERcXR/fu3Tl06BBeXl6EhIRw+fJlli5dyr0avTgQHIhDg3exLl7WdI3lqR/5pENDRo4cCcCOHTuYM2cOBw4cyKNS/DXZtUTkJakpCvGamTdvHt7e3mg0GhwcHNi+fTv25yJQsrPNE6bGExu6h4jyRdi6dStNmjRh/Pjxjw3KedVYWlq+1P5OIf5I5ikK8ZopXrw4X3/9NQAVK1Zk586dTP+/CdjYFcYyt9/QykJFkRJuXLt9lwEDBrB69WpKlChBenp6XmZdiFeeNJ8K8Zq4d+8elStXpkaNGk88f/XadTp9uYg4dQlqeTjS680SRIWfY8OGDZw6dYrp06eTlZXF9OnTsba2ZsqUKbz11lsvuRRCvNqk+VSI10R2djZ16tTh8OHDTzzfr18/BjUpjZeXF6NHj6bxB8tp3bo17733HkuWLDE1SXbt2pUVK1Ywffp0mjZtKn13QvyB1BSFeE0oikJWVhYajeYv02q1WqysrMymYQgh/poERSGEECKXDLQRQgghcklQFEIIIXJJUBRCCCFySVAUQgghcklQFEIIIXJJUBRCCCFySVAUQgghcklQFEIIIXJJUBRCCCFySVAUQoh/KSUlhYyMjL+VNiEh4QXnRvwbEhSFEOJfWrFiBZ9//vnfStulSxe2b9/+gnMknpWsfSqEKPAePnyIg4PD30p7+vRpBg0aRLFixbC3twcgMjISjUZDmTJlgJzF21NTU5kzZw4LFizA2tratDj75cuXiYmJwdfX13RPvV7P6NGjqVy58nMumfinJCgKIQq8Fi1a4O/vz2efffZM17dr146JEyfSqFEjs+NpaWlcuHABGxubp+5YotfrqVKlCkWKFHmm54vnR/ZTFEIUaHPnzqVEiRJs3ryZ5s2b8+abb5qd79+/PydOnECj0WBra0tAQADvv/8+lpaW6HQ6rK2tyczMJDExEWtrawC0eiMGRw88OgyjlocjHskXCZoz44nP79u37zMHY/H8SVAUQhRYGzduZO3atRw8eJCEhAQ6dOhAUFAQ3t7epjRWVlZ8//33VK5cmW7dumFra4uFhQUrVqzgwIEDODk5ERERwcaNG5k7dy6+73ajw5SfiN23jMQ6KVyOfUj25XP4NvJm6aIFZs9fsGAB9+7de9nFFk8hQVEIUeAYDAZmz57Nxo0b+eWXX7C3t8fe3p7NmzfTtWtXWrRoQd/Bw9gcmc7eK7+zqWd/XJwKU7yYE5ATKAFsbW0JCQlBo9Gwfft2du3aRULpFmTpDKDOqTXqjQrZOj2XYlKemBfZCPrVIkFRCFGgREVF0aVLFypWrEilSpXo0aMHFhY5A/EVRaFFixakaw3UrVkNtz4zSU7NwqHlRyiuZdGeDAL+G8jWrFmDi4sLly5d4uzZsxQrVoxzX/TDqlFvs2cajEbCQnZRu3ZtjEYjRqMRtVpNcnIyPXr0eLlvgHgqCYpCiAKlbNmyfPPNN/j6+hIfHw/8N8gpioKFhQXfhdyjtFUjFI0DimLEYFTI1OrJSM4EIDs7m61bt1K+fHlatGjBli1b6NWrFwEBAYz96Swrfzli9kynN9vh5W7P+pkB7N+/n927dxMUFMTu3bt55513Xu4bIJ5KgqIQokCxtLTE19eXKVOm8PPPPz8xjbFqWxT3nJGkxqw0EncvQGWpxsHRyXQPNzc3jh8/zurVq7l37x4LFixg48aNZGl1GF3r86hV1MpCxcPja4hPv4ZKNdb0jPj4eMaOHcuePXuYO3euqUn2r0yfPp3hw4dja2v72Ll169bRvHlzXF1dAZg2bRrly5fnvffe+9vvT0Enk/eFEAVSbGws48ePJzQ01OzHz88PZystaoucqGbMfEjJ96fi3mMqhWxy6hGKojB8+HBu3LjBtWvXGDFiBEOHDiU0NJTwi2F8P7oX7o4aarjaozm+CE/Dbxw5eIAiRYqg0+lQqVS4u7tz8uRJoqKi8PPz4+/Ojps4cSJ6vf6J57Kzs2ncuDGrVq3CYDCwePFiVq5cSb9+/Uw/77//Pqmpqc/nTcyHpKYohCiQHvUjPkmT8sX5XacmPVuPPjUR2yLOWOvScHTUAKDT6Uxp1Wo1er3eVHO7dOkSs6cF0vsdHyYMa8GPRaJNo1ZHjx7N6tWrmTRpEgAODg5s376dEydO/O0BN1ZWVqjVT/7o7tu3L82bN+e3337jhx9+oEOHDowaNcp0XlEUsrOzsbOz+1vPKogkKAohCiRFURg9ejRTpkwxOx4bG8uYMWPY9XFTvvphG5uKFadzDWfKZj5g03lr1Go177zzDk5OOU2pBoOBs2fP0qxZMwBq1KjBwYMHTUGub9++pnuPHj2asWPHUqxYMdMxKysrmjdv/szluJOQyuKjUZy5EkVJ4wOmD+tJiexsPvroI+zs7OjSpYtZ+uXLl2NpafnMz8vvpPlUCFEg6XQ6Zs6c+Vjz6YcffohOp8PNUUO3WsX4esxQxrSpwMypgfTu3Zt69eqRlpZG48aN8fLyomHDhjg7O9O2bVvTvf+s1ufi4mIWEJ+Vi4sLjo6OFCniSFm34iyaP5fwW3Gs/y6Qmm17kKFYsWLFCgoXLszhw4dp27YtoaGhNGzYEIPB8K+fn59JTVEUSMnJydjY2KBWq//2AAeRvyxevPiJxwMDA02/+/j44OPjA+RM5Xhk165dLzRvfyUuLg5bW1smbg1nzZk76I05/ZEufefw8Pga1ocl8GX7Ktja2lKoUCHS0tLIzMxEp9OhVqsxGo1PbT4uyGTtU1EgjR8/HmtrazQaDdHR0cybN8/sQ6JEiRLExsaiUqm4desWNjY2JCYmms5Xr179T/t1hHiRChUqREJCAra2tvgvDCHsfxYF0CX8RiWXwsRtmsr9+/cpW7as6dzNmzdxdXVl6dKlj63TKnLIVwVRIGk0GtRqNaNGjSI5OZmQkBAgp0lNURSsrKwwGo389NNPfPzxx/zf//0fXbp0oXfv3rRp00a+ZYtXQi0PR9MoWcjpJ43fMpUaZUqwYcMGunbtyk8//USLFi0IDQ2lWbNmnDx5UgLiU8hXXZHvHThwgBEjRmBjY2M6dv/+fQwGA5s3b0an09G/f3+ioqL48ssvuXDhAomJibRp04awsDCOHTvGwoULCQ4Oxs7OjuDgYAmKL9CpU6fo06cP165dQ6fTmZq39+3bR6VKlShdunQe5/DVMbi5J1vDYnNGyRoVdDdDsStZli+6eHM97AyOjo6UK1cOo9GIXq8nPT1dugv+gvyfLfK99PR06tatazaYYsGCBXTq1InQ0FB+/fVXjp0LZ/zmMK64taXBxzMpWqwYXbp04cMPP6RChQqmILh//37at2+fxyXKPzZu3EjFihWpU6cO1apVw8fHB1tbW4oVK0ZISAjNmjUjOTkZgMTERBo1asTWrVtp0KABFSpUwMvLy/RTrVo1Vq5cmccl+ueeNmfQYDCYTf/4X26OGnYNa0q3N12p6VYIzm9k+cxA3Bw1KIrCvn378PLy4ujRozRs2JATJ07ICjp/QWqKIt970khANzc37t+/D0C3nn04Z1kJndqe+P1LOGCpxphpZOq0aVQoX57mzZubaic7d+5k6NChLzX/+VmXLl0emzIQGRmJWq3G29sbDw8Ptu4+QJSmEmGJHviNmY/Ryp7Tp09ToUIFTp8+bZpe4OvrS926dfOiGH+bv78/06ZNo1q1akBOoG/SpAkXL140bTv1R5s3b+aTTz4xO+fo6Ej58uXN0mm1Wj799FNUVT3p2K4VgKnJ9JFp06axY8cO9u3b9yKKlm9IUBT5nqIo/Pzzz1SuXJn09HQaN27M3LlzuXHjBqmpqezYvp2Sfd9CXcQF1z6zyIqJIPnAYrpNWcTcATkfMEOHDsVgMJCVlcXdu3dNc9TEszMYDBgMhseCgb29PVqtFoAZC5bwzoIQ0tLCSTq9hWKNu3IqxUiDxpnUqVOHixcvUqdOHbKzs/ntt9+oWrVqXhTlb7O1tTUrb7FixWjatCnnzp17rJ9PURRGjhxp+vJWoUIFwsLCsLOzY+rUqVhZWTFmzJi//ey6devSp0+f51OQfEyC4l/IyMiQ1R9ecxkZGXTv3p3g4GC2bNnCgQMHcHV1JS4ujlmzZuHy5ltQxAXFaODhmS08PLUJq+JlWPX1aH75Oo2RI0cCOetdbty4kU6dOnH69Gk0Gk0el+z1duzYMUaPHo2NjQ1arZZr165Ro0YNAC5fvoy3tzfRCWnEp2ZSotsUDGlJ3FkyBPfukwk+4kbbtm3Zvn07derUYffu3abJ86+ipKQkrl69yoMHD7h48SIPHjxg0KBBpv69Tz/9FMhZZefMmTNATgvHH/vBbWxsTAH10XSif8LX1/d5FCXfk6D4BFWqVCEiIoLMzEwaNmzIxYsX8zpL4l+4d+8eDg4OQE7/jbOzMwD169dn0aJF9Jyxnm3XMsj4PRpDWhIWdg4U8+5Oy8olKBp/0WxgQvny5WnUqBH79u2Tvpl/qUWLFmzfvp07d+5QsmRJevXqZRoFXKVKFUJCQsymHDi/PYKs6ItQxIWwmGSGd/enWbNmTJgwgaVLlzJu3Li8LM5TJSYmcujQIS5dusTBgwfp2rUrp06deuyL1e37KUzc+v/t3XlUlHX///HnDDPsIIgrIm5AIpqkpqi4oGlSmhsZLrlUKlqp3VpquVVqufTTLy653Wla5p1oFiqaS6i5a7K5L6kgKKAygCzDzFy/P6Dp5nbJChmg9+MczuFa5prPZw5nXlyf67MksDNqG80a+4LaqljgX7x40fy3LJ6MChuKN27c4Pnnn8fJyQkrKytSU1Oxs7NDq9Vy584d3N3dgcK7iMWLFxMWFkbNmjVRqVQkJyfTrVs3FEXh+vXr5pkq0tLSWL16NU8//bQlqyb+pN+6out0OmJiYmjQoAGZmZn8+uuvNGrUiAk9W/H9O4uwdqpB5edGkLxiJBpjHu3rOHDseq75mZXBYGDatGns2bOH0aNHW7hWFcOJEyf48ssvmT9/PjExMTRubK4AACAASURBVDRq1IjXX38dZ2dnbt26RVMPF04nZ5oHp6ttHUGXQlOPBri5uREQEMDEiRPNnXDKKm9vb0aNGsX06dMJDAykY8eOXLp0idDQUPM5r7w6jK903tzLN5C8ZzNJOS9z+24Om37YRm5u4ZJVMTExHD58WHrgPkEVNhRr1apFQkKCeXvGjBm0aNGCGjVqsGrVKpYtW1bs/P++Gxw1ahSff/45JpOJqVOn0r17dxISErC2tpZALGdyc3PZtWsXH330EaGhody+fZvg4GCCgoIYOXIkW7ZsYcMXn+OnO4bJzg8rj/qkFmRT/doe1q78iZSUFAICAjAYDGg0Gvz9/RkxYgQeHh6WrlqF8N+TW/v7+5vvFO/evcvGjRsJG/R6sSEHmQe/we3pjoR1aADAe++9R8OGDYmMjLRYHR7XqlWrAJg7dy62trbm4SWbN29mzZo1rNsbw73a9QqHVtxOwsqtNiYTGDxbsnHjRgD69u3L7Nmz6dmzp7nFQ5SsChuKjyM5I5dl+y4Tm5RB3PIJLF4wl/kzp2NjY2O+O9TpdKxevRpfX1/u3r1LcHAw1apVs3DJxePauHEjbdu2pUGDBkRFRbFv3z6GDBlCeHg4L730Ei+++CJdunTh8uXLXLw4j3r16uG3tBbHjhwCYPHixRQUFJi7xffp08eS1anwfruDHzp0KN26dWPYsGEs7OLGnhQNB46eIN+QwaEVU3B3sePu3buMGjWKsWPHMnHiRJo0aUKdOnUsXYUHunPnDhs3biQoKIhJkyYRHR1NvXr1ijWfpujyMNRSMBXkY+XgikpjA2o1tx08Gd6/P3FxcajVasLDw9m9e7cFa1PBKRXYlStXFEdHR6V58+ZKzZo1FW9vb8XX11epWrWq8rT/M4qVvbPi8dr/KXUmbVVs3J9SqrULVV4d9oYyb9485d1331Xeffdd5bvvvlO6du2q6PV65fjx45aukvgL8vPzzb8bjUYlNTW12HG9Xq8kJiaat+/du1ei73/nzh0lPT39ocdv3rypLFu2rETfszw4e/asMnjwYKVu3bpKYGCgYmtrq/j6+ipDhgxRFEVRpk6dqoSEhCht27ZVIiIilGbNmimRkZGKoihKVFSU0qhRIyUqKkpRFEWJiIhQPD09lfXr11uqOo/0xRdfKF9//bXy4osvKhcvXlQUpbAOY8eOVRRFUVavXq10enWs0uD9bUqdSVuVOpO2Ku7DP1fs6vorU7fEK4qiKH5+fkpBQYGiKIoyb948ZcGCBZapTAVXoe8UbWxsaN68OdHR0YwePZrXXnsNKGzGqBb8Fr9OHYdRZYUVUKn9YIy3LnEmJYtL5zYzZMgQTp48SatWrZg1axZnzpzh7bff5vDhw5atlPjT/rsLvFqtpmrVqsWOa7XaYs2hf6W38Y0bN1iyZAm5ublkZWVx+/Zt0tPTyc7OxmQy0adPH6ZPn/7A1zo5OTF16lReeOEFateujaIo6PX6Yj0PKyJFUXB0dGTWrFk0b96cBg0aFOtR+eGHH/L222/z888/89xzz5kXAB41ahTnz58nMjKS+vXrA4XNiu7u7gwcOBAfH58yN15x2LBhAKxfv968b8eOHTRt2tS83aqeGzf1uShYY0RN3oVDONdrYm4qFqWjQofib7OQKIrC0aNH+eyzzzh9+jQAsUkZFD27J+tUFFmnolAM+dxp3Ap3tZqUlBT0ej3Lly/Hzs6OrVu3StOZeCCTyYSbmxudO3emcuXKVK5cmSVLltChQwfGjRtnPs9gMKBWq0lMTMTPzw9/f3/zMR8fH/r372++HsChQ4dKtyKlzNfXlyVLljz0uEqlYvHixebJ2j/55BMAZs2ahaur632TMrRu3ZoLFy6U6YnaDQYDJpOJ/fv3s3nzZvNajnZ2dlw8E0dzp+ukWlUBr7b8HLudHQcO4160sLHBYMBoNJbp+lUE/4hPNzw8nMDAQOzs7MwrXTucPIuSnw+AY9Ou5Jw/SCX/blRXUlDSbpKQkEBaWhp169alffv2zJ8/n3Pnzlm4JqIsOn36NK+99lqxO7vr16+j0WiIiIgw78vJ19M0ZAzJBkecqnvy7dZd5i+86dOn0759ezp37lzq5S/r/nee2UdNnFDWA6OgoICcnBwmTJjA8uXLcXR0BKBbt278+uuvqFQqlowezZQpU2g+eiTPNvY2v3bWrFnmzyIvL++BM+CIv69CLx118+ZNQkNDGTFiBL169TI3i8XGxnLlRhqvvz8Hh2d7o3arza21E6jcpANvPedL1A+bGTNmDIcPH2bGjBl88cUXREREsH//fpkIWjzU3r17OXPmDFA4HZy9vT0dO3YEwLVGbeaeseNevoE8XRrpm2fhM3IRO8a2x93FjkGDBjFo0KBiC9WKiis/P/+RzeNGoxGTySSTd1tAhQ7FlJQUGjZsaJ4l43+dv3CRPh98zolTMWhu/0oVVRaT3h3PBx98QGZmJpmZmXTp0oWTJ0+iVqvp3LkzderUISwsrJRrIsqDUaNG4ezszLPPPsu3336Lg4MDL774IqdPn2bjnqPktXursLv93RRub1uATRVPHLKuU7+GKwkJCTg6OlK3bl1MJhP169fnq6++snSVhPjHKdttDX9Tfn4+zzzzDNHR0Q88PnToUIa39WRKn2fR6XT07duXNm3asH//fgB++ukn5s6dS1RUFNnZ2XTt2pXly5eXYg1EeaJSqdi0aRN79uwhOTkZjUZDfHw8Op2O3Ep10RQ9xDZm3UZt64hrt7do6lGJiBGtqFOnDm5ubhw4cOCBE5gLIUpHhb5TVBSFvLy8x56j8o+aNIR4lPDwcK5cuYKLiwvR0dHY2toSEBCATqcjNl3humdXDCaFe6ej0adeoVrn1+nf0hPvzFPs3buXzMxM+vbty4ABAyxdFSH+sSr0naJKpfpTkzZLIIq/6sKFC2zYsAEHBwesrKxISkoyPw9SFIVsXRYmVXU0tZuSl5iAg6cf9jYaejSwoe8LHxAdHU1BQQHPPfccAQEB5qEG4s/R6XRotVqZxF/8ZRU6FIUoLT4+PsWGUMyYMQMXF5diQzKSM3L5f5EnWLToKMPHTqSXnyuhPbvx6aefmkNwwYIFtG/fnlWrVkmnm79g7dq1nDt37pFDPYR4lArdfCpEaUhOTuaFF14wTz7/2z6NRmOeElBRFLKysnjllVe4efMmb731Fm3btiU8PJx+/foVu150dDQjRoxgzZo1tGnTptTrU14cPXqU4cOH4+bmhoODA1C4QLGdnZ15urffPveFCxfSrFkz3n77bSIjI3FxcbnvepmZmVy5cqVU6yDKHglFIUqZyWRCrVaj0+moVKnSI88Rf05wcDDTpk176IoZ48ePx2AwPPD4jBkzZCyykOZTIUrbb2H3sED873PEo3Xt2pWcnBzz9qlTpxg7dmyxge31vBtSr9c4YpMyuHkhlYCn3B+4woTRaCyVMouyTUJRCFFuxcTEEBcXh0ajYd26dealpxYuXMjQoUM5cDyWASPHUd39OgaTQla2FXFfR7B7ZxRaq+L/eHh7ez/oLcQ/jPw7KoQoUV26dGHv3r3m7evXr9OzZ0/zQrlQOIF6TExMsdclJibi6+v7p97rt2nS3Nzc2L17N9euXSMyMpKoqCgcHR357lQSJiuteZFip4CX8XhtEX1nricmJqbYz/bt2/9qlUUFIneKQogSZWNjY26+LCgooH///jRu3Lj42oEpKYSEhLBw4UJ69eoFgK2tLdbW1uTl5XH27FmeeeaZP3yv35qZAwICUKvVDBw4kPPnz5snaDc9O4Dfek3c3h5O3rVY1HZOhK+zYvvHjsWulZWVha+vL1u2bCmJj0GUUxKKQognZuTIkVStWpWlS5cW29+iRQs2btxIamoq8fHxLFu2jA8//BCVSsX169fp1asX4eHh9OzZ8w/fQ6/XExUVhYuLC3PnzqV79+5MmjSJnJwc3ly0mV9+myDISoO9bzsc6/kT1LAaQ9vUK3ad2NhYDhw4UFJVF+WUhKIQ4okYM2YMZ8+eZe/evb8PVcnIZcnuc+zZu4euz3cjrEMnvv9mDbdu3TK/zsfHh23bttGpUydsbGweOV5TURSio6NZsGABVlZW3Lx5E4CIiAiMRiM9+vTDSq1Co1aBSoXKoEdjzKN9HQcyMjKKXSs7O/sJfAqivJFQFEL8bSaTCUVRzOEHheslTps2zdxsmpyRS7cF0WTq7nIzcjWn929jy8uTeOrcwfvuCBs3bsz27dvx8fF55Pvm5OTQtWtXBg8eDMAnn3yCSqVi0qRJABw5coRDP++nTUtP1h3QcvfcURzzfmXp+cj7rpWdnU2jRo3+1ucgyj8JRSHE33bgwAGGDRuGtbU1SUlJxMfHY2Njw5gxY2jQoHDl+PTsfHTZuVTt/T7V+88i72osOfkF7Nj5I0vDF5iDFTBPmdeiRYtHvu+9e/eKbf/34sPx8fFMnjyZTp06MbVnY+7sqkW7NxfwyiuvPPBa0dHRzJkz5+9+FKKck8H7QogS9dszvcDAQJo0acK3336Lr68vPZf8TGySznzenV3LqRQ4gCq34zi1bjaJiYl06dKFQ4cO4evrS3h4+EMD7HEpiiKrjog/RYZkCCGemIkTJzJ69GiMRiNNPVwKn+0B+SkXybsej62DMz1CClcF8fDw4MSJEwwcOJBevXr97UAEJBDFnyahKIR4IrZu3Ur9+vVxcnJiyJAhDAvwwMFGg0atIjt+N85PP4e9jYawDoXNq5cvXyY4OBh7e3sWL15s4dKLfyoJRSFEidLr9UycOJGwsDDu3r3LN998Q3p6Oj06BzLOK4NgTxW5CXsYGPoKP4wK4HL8Cd544w1atWpFnz59iIiIMC+7JURpk442QogSYzKZOHfuHM8//zw7d+40zzgTFRXF0qVLOXPqOB+9/z5Pq8MZ/sZzREVFMXnyZAYMGMClS5dwdXW1cA3EP510tBFClKjk5GTc3d0tXQwh/hIJRSGEEKKIPFMUQgghikgoCiGEEEUkFIUQQogiEopCCCFEEQlFIZ6g5cuX895771m6GEKIxyS9T4UoYa1btzavFpGamkpubi516tQBQKfTsWPHDmrVqoW3tzfVq1cnKysLtVrNzJkzGTZsGJ6enuZr3bx5k6SkJIvUQ4h/Ihm8L0QJu3btGsnJyQCsWbOGS5cuMXPmTAA6duxono9Tq9USHR3NypUr0el0WFtb88ILL7BmzRoADAaDeYUJIUTpkFAUooQ988wzBAYGAoV3inl5eURHRwOgN5iY/+MFLt+7Qvq9ApIzctm0aROLFy9+4B2hTGgtROmSUBSihMTExHDkyBF69+5t3nfo0CFSU1Pp1asXGTl6Fu65yLr/bMKqiicZOQUEz43izpkzNGzYUJpJhSgDJBSFKCGOjo7UqlWr2GTW/fr1M/++9/BVTHauqKyNqG3sAYV8tS22VTyJjIzEzs6OrVu3/uHCuqJsUhSFmTNnMnHiRLRaLXq9Hhsbm2Ln6PV6NBoNarX0cSyrJBSFKCFeXl54eXnRq1cvzpw5g7Ozc7HjF1Lukpuvp9bwZeZ9BQrU7zGa+fPnM3XqVLp3717smaKXl1dpVkH8DSqVCo1Gw7Bhw5g/fz69e/dGoyn+FZufn8+XX35Jo0aNUBQFT09PEhMTAfD29iY2NhZ7e3tmzZqFVquVnssWIKEoRAmztrYmPDycbt268fnnn/PUU0/RqVMnxqzYyfIpYcXO1apVBDRtxOp/n7dQaUVJMJlMKIrCpEmTiI6OpmbNmuzatQudTmc+56Yul29j05n80x2aXkwgrEODYneSNjY2WFtbm3//30AVpUM+dSFKWEFBAVD4RblixQoWLVrEtWvXGBLYgNXOldGoVRhMCipUKDfPsWHSODp37mzhUou/Iy4ujrCwMDQaDRcvXmTevHmkp6ezefNmvLy8yNEb2X4oFm0tXyq1H8yxfbv5z24PUFuxY8cO2rdvD8DFixfva2EQpUtCUYgStnTpUnJycnj11Vfx9fWlUqVKBAcHU6NGDf7vw/f41aE2cTd03LO1InL6QPQZXfD392fXrl1ERUWZe65C4XMqUfb5+/tz5MgR9Ho97du3p1+/fixbtgw/Pz/atWtHxMlErKpkYKKwN7HuVBRWrV8mL0fPzp07yc3NBQo7ax0+fLjYWFVRuiQUhSghBQUFDBw4kLi4OBwdHRk1ahSvvfYaKpWKM2fOcPDgQT766CM8PT35fuVKGvw/8PGohqZu4dqDGo2GoUOHMmfOHACMRiN9+vSxZJXEnzRjxgwGDRqEra0tPXr0MD8TTsm9gU29ZmhdagJQcDsJtVtt8g0mQkJCWLJkCQB9+/Zl9uzZ9OzZkypVqlisHv9kEopClBCtVsv06dOpXr36A7/Q2rZty86dO7l79y4Aly9fLnY8KCiIoKAg87aVlRXff//9ky20KDFr165l/vz51K9fnxo1ajB06FD8/f1JS0vj5m0dejs39OmJVA2ZipWDK9bWtthaawkICODOnTvExcWhVqsJDw9n9+7dlq7OP5b0CxaiBPn5+f3hf/iurq6lVBpRWvbs2cPKlSsZMGAAkydP5tixY3h5efHzzz8zdepUXh00CJ/hC7D19ENlpaX24LlY5aTh26AOVlZW9OjRw3ytoKAg+RuxILlTFEKIv6lDhw5ERkYyadIk6tSpwyuvvMLSpUsJDAwkLS2NnJwcatY6hJJyFp9qjnRo6Un+8WM4BHWwdNHF/5BQFEKIv0mj0eDi4gIUdo5SFMV8p/jVV1+RkJDAp59+Sq9evZjSz5+6dWvQeOQyjh8/br6GwWDAaDSWyFAMk8mEyWSSYR1/gXxiokIwmUwyS4iwuLy8PPR6PQUFBVy6dKlYT+LAwEDOnj2LXq/n448/5vXXX6d27drm47NmzTL/Defl5ZnHLG7cuJFdu3axfPnyB86FGxMTg7+/f7F977zzDr6+voSFhd13vng0WTpKlDvjx4/nqaeeYsSIEQAkJyfTt29fDh8+/MDzY2NjGT16NAcPHsRkMlGtWjXS09NLs8jiH0Kn02Fra3vf9G7/y2g0YjKZik0J+CBpaWk888wzLFy4kJCQEOLj49FqtTRs2BAo7PH80ksvUadOHRo1asT69evRarWkp6eTnZ2Nh4cHNjY25OTksGzZMpo1a1Zida2o5E5RlDvW1tbFvkzc3d3R6XQcO3aMli1bArBv3z7CwsJwcHAgPz+fq1evmucUzczMNP+enZ3Npk2b8PPzK/2KiAqnUqVKj3WelZWVec3Nh8nLy6N37968++67hISEAJCQkMDkyZPZu3cv9evXR6vVsm3bNubMmWNei1Oj0XDkyBFCQ0OZP38+H3zwAXXr1v3DABaFJBRFuWEwGADMTUx6vZ6MjAzs7e0ZNWoUer2ei0lprIi+wPkMNS9/upGwDg3ISb/B4sWLWbhwIQBvvPEGs2fPplq1aharixCPkpycTGhoKEFBQbz55pvodDoyMjLw9fUlKCiI5557js1Re1j101lOX0+jXaserFq7nu/+8zVjx44tdq2oqCi+/vpr1q1bh4+Pj4VqVH5I86koN3788UemT59OUlIStra2DBo0iH379pmfveQbjJy4dhejwUiVvlPJPLAOrRp6+tciKLA1/fr1Q61Ws23bNpYvX87WrVsxGAxoNBpZt1CUKWPGjGHRokVUrly52I+rqyuurq5cTbzB3hOncev2Fre2zKVSsxewKrjHjytn42qrJi0tDR8fH65cuULTpk3ZvHkznp6esgLLY5BQFOXOlClT8PLyYujQoeh0OgwGA25ubkz7PoHlX3yJulJ1bGr5krR0GNV7/AvV8W9YufBTEhIS2LRpE7a2tkBhL8H8/HwiIiLw8PCwcK2E+F1KSgpGo/Ghf5dTv4vji8070Hr4YczNJOuX7VRt15+qZyLQ3L5UrNPZ9evXuXLlSmkVvdyT5lNRLv34449cvXoVtVqNXq9n5syZxCZloDu1g0oBfQFQaWzA0Y0cvZHg4GCCg4O5du0aAwYMwM/Pj65du7J///4/7BQhRGmrWbMmAQEBD114Oltlj8ugBQBY2Tnj+HQX9Pp8FHc/+nUu3plm1apVT7y8FYn0YRflRkpKCh9//DGrV69Go9Ewbtw4QkNDWb9+PQCNazhguJ2Ebd3fu6fbOFTCGgO3bt2iV69exMXF8f7779OxY0du3bpFYGAgW7ZssVSVhHio27dvEx0dTVJSUrGfI0eOoORloVH/3uSv+/lrChLjST24CTs7Ozw8PMw/n3zyiQVrUf7InaIoN1JTU7G2tiY0NJQmTZrg4uKCi4sLTk5OHD16lFZOuTjWbYxWa120NBM4VXKhZduWfPnll/zyyy9cvHhR7gxFufCo3qnOdtY42Gi4l28g904KRl0qVRsFYHttJ0uXLi32jDwzM5Nr167JmMXHJKEoyo2mTZvStGlTpkyZUmx/9+7dzc8KP3p7KOk1PYlNyiDbTkM/2wS+ifmFCePGsGTJEglEUW6YTCbatWt3XzgajUasra2JGtOOZfsus3L6HEJef5tP32qH+7SD910nNDSUunXrllKpyz8JRVHumEwmoHDgskajYcKECdjZ2dG2bVt2796Ns7MzJpOJxuHWTJ4wjg/e+xf/+te/GDhwoIVLLsTjMxgMHDhwwLz81G+SkpJ49tlncXexY3SrKtxo7sW/p7x23+tnzJjBhg0bqFOnjnkRY/HHpPepKFemT5/O+vXrWbRoEd999x3x8fH3Te9mNBoJCQlh0aJFXL16lR07djBv3jy2bdtm7nkqRFmXk5ODnZ3dXx4uZDQa/3CCAHE/CUVRrkRGRuLq6lpsTkkhhCgpEopCCCFEERmSIYQQQhSRUBRCCCGKSCgKIYQQRSQUhRBCiCISikKIJ85oNFq6CEI8FglFIcQT9dVXX/HGG29YuhhCPBYJRSHEE9W9e3eOHz9OTk7OA48rikLt2rXN297e3uZzZ82axdy5c0ulnEKATPMmhChhZ8+epVu3btjZ2Zn3KYpCs2bNzL9nZWXxzTff0KFDB1QqVbE5aW1sbMwLR9vY2KDRyNeUKD3y1yZEGabT6dBqtdjb21u6KI9Nq9Xi4ODAmTNnHnpOckYuy/Zd5r2wOTRr7AtqK3bs2GGeo/PixYs4OzuXVpGFMJNQFKIMW7t2LefOnWPJkiV/eO7s2bNp27YtHTp0KIWSPZytrS0FBQUPPZ6ckUtw+AHu5RtI3rOZpJyXuX03h00/bCM3NxeAmJgYDh8+jKenZ2kVWwhAQlGIMuPo0aMMHz4cNzc3HBwcADh37hx2dnZ0794d+L3pceHChebmyN94eHiwcuVKi4ci/L6SyYMs23eZe/kGDCaFgttJWLnVxmQCg2dLNm7cCEDfvn2ZPXs2PXv2pEqVKqVVbCEkFIUoK1q1akVcXFyxfcHBwUybNo3WrVub9yVn5LJ491maN1dRuaYnro62xVZhb9iwofn3K1eukJCQgI+Pz5OvQJHc3NxHrlsZm5SBwaRgKsjHysEVlcYG1GpuO3gyvH9/4uLiUKvVhIeHs3v37lIrtxAgoShEmdK1a9divTRPnTrF2LFjzR1P9AYTl42uuHQeCYDzK5/i4OpG1Jh2uLvY3Xc9Ly+vUl8+KDk5+ZF3d009XDidnIlBa0ONQXMouJ2IxrEy/p5u9OjRgcmTJwMQFBTEyZMnS6vYQgAyJEOIMiUmJoaIiAi2bNlC3759uXfvHseOHSMkJIStW7fSuM+b5KbdwICamsPCMWntyck3sGzf5Qdeb/Xq1dSoUaNU67Bv3z4aN2780ONhHRrgYKMx393mXTiEc70mhHVoUFpFFOKhJBSFKEMcHR0BcHNzY/fu3Vy7do3IyEiioqJwdHTkYmo2aKxRqVSkb/2Mm2vHc/2LsYS/HUL9+vWpUqUKLVq0oEWLFjRv3pzRo0c/stNLScvMzOTzzz/n5Zdffug57i52fDO4MQNaetLQRSE/djuR4VOp7mTNtWvXyMjIYMqUKSQkJJhf8+9//5v09HTz9qhRo9i7dy8ArVu35s6dO0+uUuIfRZpPhShD1OrC/1MDAgJQq9UMHDiQ8+fP4+bmRufOnfF+cQS/FD0+dH+9sEeqVq2if0tPfLJi2L17N2vWrLFQ6eHkyZO0adOGoKAg8774+Hhq1apF5cqVzfte6fE8P/zwAyvDhuNkq2XM8MEkJibi5eWFSqVCpVKh0+nIzs7G1taWzMxM2rZty/79+6lSpQrW1tZotVoArK2t0Wg05OfnP/JZphCPQxYZFqIM8fLyYu/evTg6OuLi4mKezWXSpEnk5OSw68BRXh0ziWoh0zGYFLRqFfY2GqLGtGPv1k0WD8UH+frrr/nss8/YsWMH/fr1w2AwcPr0aZo0aYKiKKjVarp37869e/do0aIF+/bt4+DBgxw8eNAcko6OjmRmZqJSqbhx4wY1atSgRo0auLi4cOzYMZo1a0aVKlXYsGGDpasryjm5UxSiDFEUhejoaBYsWICVlRU3b94EICIiAqPRyMCBA2lZtzJtWnoSm5RBUw8Xwjo0eGAnm7Ji4MCBZGdnc/z4cUwmE+PHj6dx48YEBwdTqVIljEYj06ZNQ1EUNBoNLi4ueHh4EPRcVwx2rjR5fQ6e1veYMrAL+oxbdOrUiZdeeomQkBACAwPp2LEjW7ZsMTc9C/F3SCgKUYbk5OTQtWtXBg8eDMAnn3yCSqVi0qRJABw5coTo6Gg+6vnwjixlicFgYP/+/YwcWdhbdt68eSQmJpKamkpgYCAZGRnojZCYpsOtcSA3jm7H2cWVgcNGsOqWB9p8A6fOXWbXd5/w/bZg2rpkkpKSwnfffcfhw4dxdXUlNjaWPn36kJuby4oVK/D19bVwrUV5JqEoRBly7969Ytuurq6oVIUPEePj45k8eTKdOnW673WjR49mw4YNjB8/vlTK+bju3LnDHC+KkgAABkFJREFU5MmT6dixI59++ikAUVFR3Lp1i3PnzqFSq1FX90FdszGp94zoFSsK2oax9KtNXL36Kw5PP499w7ZUHzQXU9qv1GjXlJpHDlGjRg12796Nvb09EydOpHHjxrz66qsWrq2oCOSZohDliKIo5pD8b6mpqWg0mmKdWcqKvLw81q1bx/Dhw+nYsSNr167lxRdfpHLlyly9ncONq5dRAK1rTfQ3L6N188CUfRt7vyCMOZm4Bb+NykqDYjLikX+dE5+Pp3379rRq1QoonCxg7dq1TJgwgXfeecc8plOIv0KGZAhRjjwoEAGqVatWJgMRCudC1Wg0FBQUkJOTw9ChQ5kzZw41a9YkDy3aavWw925FjUFz0bhUp8pLE3D2eRbHp1pTpfs7qKw0GHMzSds4gztHv8fFxYXc3FxCQ0MJDQ0lOzub+fPnc/nyZXbt2mXp6opyTu4UhRBPVEZGBq1ateL06dOsWrWKESNGkJaWxsyZM0mxr8eWZZ+gsrbHys4ZfcpFtFU90eTcoebLU6GaNwaTwr1ftqHOy+CHRdN45aVu6HQ6/Pz8gMIm2lmzZtG7d28L11RUBBKKQognavny5dy6dYusrCxOnDiBjY0Nly9f5urVqzTwfopfUzOwcqqCY4ue6KK/pG7oFJre3sfAIa9xMq8qMdfvcGjuUCIjt1LTxZ6OHTvi4+PDjz/+aH6Pw4cPk5aWxksvvWTBmoqKQJpPhRBPjKIoLF26lMGDBzNv3jx++ukn3nzzTapVq8aXX36JjdYKV62JKnZqjL98hynzFtb7l7Bvz4+42Kr5qGdjPmhpQ/NG3jRv5MWlS5ewt7fnypUrtG7dmsDAQAIDA+nfv7+lqyoqCOl9KoR4Yi5duoSPjw8eHh6MGzeOn3/+mXbt2hEVFYWzszNPPfUUY8aMAQqncuvevTsb//NNsZU+WrVqxdatW1mxYgUfffQREyZM4N1337VUlUQFJ82nQohSceHCBerWrfvA3qFnzpzB19f3oR2J4OE9b4UoSRKKQgghRBF5piiEEEIUkVAUQgghikgoCiGEEEUkFIUQQogiEopCCCFEEQlFIYQQooiEohBCCFFEQlEIIYQoIqEohBBCFJFQFKIC27BhAykpKebt2bNn8+2331qwREKUbTIhuBAVWH5+Pm3atOHjjz+mf//+rFixgiZNmrB9+/Zi56xYsQInJycLllSIskHmPhWigrt69SqJiYmcPXuW+Ph4xo8fbz6mKAr5+fl4e3tz48YNvL298fX1feB1zp8/z6lTp4qtYCFERSN3ikJUUImJiVy4cIHOnTuTn5/PyJEjsbe3JyQkpNh5c8OXsX7rWY6euYxD5epsjz6Mu4vdfdfz9/dHq9WWVvGFsAh5pihEBZWRkcHo0aMZO3Yszs7OrF27FicnJ6Kjo+nWrRsnTpygyTMtCPvqOOuPXefMzXtk5RsIDj9AckbuA69pZWVVyrUQonRJKApRQTVp0oQTJ05gZWVlXtDX1tYWR0dHsrOzyc3NJe76bfIMUGA0Fr5IgZx8A8v2XbZs4YWwEGk+FaICc3JyYvjw4SQmJtKnTx9SU1Np0aIFAO3atSP+7AX45RhuwW+jcXUHoMCkEJuUYcliC2ExcqcoRAWmKAp9+vTB3t6ejRs38vLLL/Ptt9/SsWNHTpw4Qb3GLfAY8hk2tX7vXKNVq2jq4WLBUgthORKKQlRg27Ztw8/PD09PT9LT03FxcaF+/fqYTCYMBgPV7VU42NmgUasAUKnA3kZDWIcGFi65EJYhzadCVFCKovDhhx+yYMEC8/auXbvYtWsXAAEBAZw9e5bmLKT3uP/j2FkjKVnpGDZO4IXN9/+/fP78eUwmU6nWQYjSJqEoRAWVkJCAu7s7gYGBAOYm09/Mnj2brVu3sv+nPQAkNqtE0CpPTsfHPfB6/v7+6PX6J19wISxIBu8L8Q+1c+dO/Pz88PDwsHRRhCgzJBSFEEKIItLRRgghhCgioSiEEEIUkVAUQgghikgoCiGEEEUkFIUQQogiEopCCCFEEQlFIYQQooiEohBCCFFEQlEIIYQoIqEohBBCFJFQFEIIIYpIKAohhBBFJBSFEEKIIhKKQgghRBEJRSGEEKKIhKIQQghRREJRCCGEKPL/AZBRJtwZJIyDAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "nx.draw(city_graph, city_location, with_labels=True, node_size=30)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "simple_connection_info = {\n",
    "    '北京': ['太原', '沈阳'],\n",
    "    '太原': ['北京', '西安', '郑州'],\n",
    "    '兰州': ['西安'],\n",
    "    '郑州': ['太原'],\n",
    "    '西安': ['兰州', '长沙'],\n",
    "    '长沙': ['福州', '南宁'],\n",
    "    '沈阳': ['北京']\n",
    "}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### BFS 广度优先"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "def bfs(graph, start):\n",
    "    visited = [start]\n",
    "    seen = set()\n",
    "    \n",
    "    while visited:\n",
    "        froninter = visited.pop() #last element\n",
    "        \n",
    "        if froninter in seen: continue\n",
    "        \n",
    "        for successor in graph[froninter]:\n",
    "            if successor in seen: continue\n",
    "            print(successor)\n",
    "            \n",
    "            visited = [successor] + visited #每次扩展优先考虑已经发现的老的点 --BFS\n",
    "            #visited = visited + [successor] #优先考虑最新发现的点 --DFS\n",
    "        seen.add(froninter) \n",
    "        \n",
    "    return seen"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "number_graph = defaultdict(list)\n",
    "\n",
    "number_graph.update({\n",
    "    1: [2, 3],\n",
    "    2: [1, 4], \n",
    "    3: [1, 5],\n",
    "    4: [2, 6], \n",
    "    5: [3, 7],\n",
    "    7: [5, 8]\n",
    "})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "3\n",
      "4\n",
      "5\n",
      "6\n",
      "7\n",
      "8\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "{1, 2, 3, 4, 5, 6, 7, 8}"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "bfs(number_graph, 1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "nx.draw(nx.Graph(simple_connection_info), city_location, with_labels=True, node_size=30)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "def search(start, destination, connection_graph, sort_candidate):\n",
    "    pathes = [[start]]\n",
    "    \n",
    "    visited = set()\n",
    "    while pathes: #we find pathes\n",
    "        path = pathes.pop(0)\n",
    "        frontier = path[-1]\n",
    "        \n",
    "        if frontier in visited: continue\n",
    "        successors = connection_graph[frontier]\n",
    "        \n",
    "        for city in successors:\n",
    "            if city in path: continue\n",
    "            new_path = path + [city] #DEPTH FIRST SEARCH\n",
    "            pathes.append(new_path)\n",
    "            \n",
    "            if city == destination: return new_path\n",
    "        \n",
    "        visited.add(frontier)\n",
    "        \n",
    "        pathes = sort_candidate(pathes) #增加一个排序函数，对结果进行排序"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [],
   "source": [
    "def transfer_station_first(pathes):\n",
    "    return sorted(pathes, key=len)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "metadata": {},
   "outputs": [],
   "source": [
    "def transfer_as_much_as_possible(pathes):\n",
    "    return sorted(pathes, key=len, reverse=True)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 46,
   "metadata": {},
   "outputs": [],
   "source": [
    "def shortest_path_first(pathes):\n",
    "    if len(pathes) <=1 : return pathes\n",
    "    \n",
    "    def get_path_distance(path):\n",
    "        distance = 0\n",
    "        for i in len(pathes):\n",
    "            distance += get_geo_distance(pathes[i] + pathes[i + 1])\n",
    "        #for station in path[:-1]:\n",
    "        #    distance += get_geo_distance(station, path[-1])\n",
    "            \n",
    "        return distance\n",
    "    \n",
    "    return sorted(pathes, key=get_path_distance)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['兰州', '西安', '长沙', '福州']"
      ]
     },
     "execution_count": 49,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "search('兰州', '福州', simple_connection_info, sort_candidate=shortest_path_first)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [],
   "source": [
    "def pretty_print(cities):\n",
    "    print('🚗->'.join(cities))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "兰州🚗->西安🚗->长沙🚗->福州\n"
     ]
    }
   ],
   "source": [
    "pretty_print(search('兰州', '福州', simple_connection_info, sort_candidate=shortest_path_first))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 57,
   "metadata": {},
   "outputs": [],
   "source": [
    "city_connection = defaultdict(list)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "metadata": {},
   "outputs": [],
   "source": [
    "for c1 in city_location:\n",
    "    for c2 in city_location:\n",
    "        if c1 == c2: continue\n",
    "        \n",
    "        distance = get_geo_distance(c1, c2)\n",
    "        \n",
    "        if distance < 300:\n",
    "            city_connection[c1].append(c2)\n",
    "            city_connection[c2].append(c1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 59,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "defaultdict(list,\n",
       "            {'兰州': ['西宁', '成都', '银川', '西宁', '成都', '银川'],\n",
       "             '西宁': ['兰州', '兰州', '成都', '拉萨', '成都', '拉萨'],\n",
       "             '成都': ['兰州', '西宁', '兰州', '西宁', '拉萨', '重庆', '拉萨', '重庆'],\n",
       "             '银川': ['兰州', '重庆', '兰州', '重庆'],\n",
       "             '拉萨': ['西宁', '成都', '西宁', '成都'],\n",
       "             '重庆': ['成都', '贵阳', '成都', '贵阳', '银川', '银川'],\n",
       "             '石家庄': ['郑州', '济南', '太原', '北京', '郑州', '济南', '太原', '北京'],\n",
       "             '郑州': ['石家庄', '武汉', '石家庄', '武汉', '长沙', '太原', '长沙', '太原'],\n",
       "             '济南': ['石家庄', '石家庄', '合肥', '北京', '天津', '合肥', '北京', '天津'],\n",
       "             '太原': ['石家庄', '郑州', '石家庄', '郑州', '呼和浩特', '呼和浩特'],\n",
       "             '北京': ['石家庄', '济南', '石家庄', '济南', '天津', '天津'],\n",
       "             '贵阳': ['重庆', '南宁', '重庆', '南宁'],\n",
       "             '南宁': ['贵阳', '海口', '贵阳', '海口'],\n",
       "             '武汉': ['郑州', '南昌', '长沙', '郑州', '南昌', '长沙'],\n",
       "             '南昌': ['武汉', '合肥', '武汉', '合肥'],\n",
       "             '长沙': ['武汉',\n",
       "              '郑州',\n",
       "              '广州',\n",
       "              '武汉',\n",
       "              '郑州',\n",
       "              '广州',\n",
       "              '香港',\n",
       "              '澳门',\n",
       "              '香港',\n",
       "              '澳门'],\n",
       "             '合肥': ['济南', '南京', '济南', '南京', '南昌', '南昌'],\n",
       "             '天津': ['济南', '北京', '济南', '北京'],\n",
       "             '南京': ['合肥', '杭州', '合肥', '杭州'],\n",
       "             '杭州': ['南京', '南京', '福州', '上海', '福州', '上海'],\n",
       "             '福州': ['杭州', '杭州', '台湾', '台湾'],\n",
       "             '上海': ['杭州', '杭州'],\n",
       "             '台湾': ['福州', '福州'],\n",
       "             '广州': ['长沙', '香港', '澳门', '长沙', '香港', '澳门'],\n",
       "             '香港': ['广州', '长沙', '广州', '长沙', '澳门', '澳门'],\n",
       "             '澳门': ['广州', '长沙', '香港', '广州', '长沙', '香港'],\n",
       "             '海口': ['南宁', '南宁'],\n",
       "             '沈阳': ['长春', '长春'],\n",
       "             '长春': ['沈阳', '沈阳', '哈尔滨', '哈尔滨'],\n",
       "             '哈尔滨': ['长春', '长春'],\n",
       "             '呼和浩特': ['太原', '太原']})"
      ]
     },
     "execution_count": 59,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "city_connection"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "北京🚗->石家庄🚗->郑州🚗->长沙🚗->广州\n"
     ]
    }
   ],
   "source": [
    "pretty_print(search('北京', '广州', city_connection, sort_candidate=transfer_station_first))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 63,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "北京🚗->石家庄🚗->郑州🚗->武汉🚗->长沙🚗->广州\n"
     ]
    }
   ],
   "source": [
    "pretty_print(search('北京', '广州', city_connection, sort_candidate=transfer_as_much_as_possible))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Machine Learning"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "data = load_boston()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'data': array([[6.3200e-03, 1.8000e+01, 2.3100e+00, ..., 1.5300e+01, 3.9690e+02,\n",
       "         4.9800e+00],\n",
       "        [2.7310e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9690e+02,\n",
       "         9.1400e+00],\n",
       "        [2.7290e-02, 0.0000e+00, 7.0700e+00, ..., 1.7800e+01, 3.9283e+02,\n",
       "         4.0300e+00],\n",
       "        ...,\n",
       "        [6.0760e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,\n",
       "         5.6400e+00],\n",
       "        [1.0959e-01, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9345e+02,\n",
       "         6.4800e+00],\n",
       "        [4.7410e-02, 0.0000e+00, 1.1930e+01, ..., 2.1000e+01, 3.9690e+02,\n",
       "         7.8800e+00]]),\n",
       " 'target': array([24. , 21.6, 34.7, 33.4, 36.2, 28.7, 22.9, 27.1, 16.5, 18.9, 15. ,\n",
       "        18.9, 21.7, 20.4, 18.2, 19.9, 23.1, 17.5, 20.2, 18.2, 13.6, 19.6,\n",
       "        15.2, 14.5, 15.6, 13.9, 16.6, 14.8, 18.4, 21. , 12.7, 14.5, 13.2,\n",
       "        13.1, 13.5, 18.9, 20. , 21. , 24.7, 30.8, 34.9, 26.6, 25.3, 24.7,\n",
       "        21.2, 19.3, 20. , 16.6, 14.4, 19.4, 19.7, 20.5, 25. , 23.4, 18.9,\n",
       "        35.4, 24.7, 31.6, 23.3, 19.6, 18.7, 16. , 22.2, 25. , 33. , 23.5,\n",
       "        19.4, 22. , 17.4, 20.9, 24.2, 21.7, 22.8, 23.4, 24.1, 21.4, 20. ,\n",
       "        20.8, 21.2, 20.3, 28. , 23.9, 24.8, 22.9, 23.9, 26.6, 22.5, 22.2,\n",
       "        23.6, 28.7, 22.6, 22. , 22.9, 25. , 20.6, 28.4, 21.4, 38.7, 43.8,\n",
       "        33.2, 27.5, 26.5, 18.6, 19.3, 20.1, 19.5, 19.5, 20.4, 19.8, 19.4,\n",
       "        21.7, 22.8, 18.8, 18.7, 18.5, 18.3, 21.2, 19.2, 20.4, 19.3, 22. ,\n",
       "        20.3, 20.5, 17.3, 18.8, 21.4, 15.7, 16.2, 18. , 14.3, 19.2, 19.6,\n",
       "        23. , 18.4, 15.6, 18.1, 17.4, 17.1, 13.3, 17.8, 14. , 14.4, 13.4,\n",
       "        15.6, 11.8, 13.8, 15.6, 14.6, 17.8, 15.4, 21.5, 19.6, 15.3, 19.4,\n",
       "        17. , 15.6, 13.1, 41.3, 24.3, 23.3, 27. , 50. , 50. , 50. , 22.7,\n",
       "        25. , 50. , 23.8, 23.8, 22.3, 17.4, 19.1, 23.1, 23.6, 22.6, 29.4,\n",
       "        23.2, 24.6, 29.9, 37.2, 39.8, 36.2, 37.9, 32.5, 26.4, 29.6, 50. ,\n",
       "        32. , 29.8, 34.9, 37. , 30.5, 36.4, 31.1, 29.1, 50. , 33.3, 30.3,\n",
       "        34.6, 34.9, 32.9, 24.1, 42.3, 48.5, 50. , 22.6, 24.4, 22.5, 24.4,\n",
       "        20. , 21.7, 19.3, 22.4, 28.1, 23.7, 25. , 23.3, 28.7, 21.5, 23. ,\n",
       "        26.7, 21.7, 27.5, 30.1, 44.8, 50. , 37.6, 31.6, 46.7, 31.5, 24.3,\n",
       "        31.7, 41.7, 48.3, 29. , 24. , 25.1, 31.5, 23.7, 23.3, 22. , 20.1,\n",
       "        22.2, 23.7, 17.6, 18.5, 24.3, 20.5, 24.5, 26.2, 24.4, 24.8, 29.6,\n",
       "        42.8, 21.9, 20.9, 44. , 50. , 36. , 30.1, 33.8, 43.1, 48.8, 31. ,\n",
       "        36.5, 22.8, 30.7, 50. , 43.5, 20.7, 21.1, 25.2, 24.4, 35.2, 32.4,\n",
       "        32. , 33.2, 33.1, 29.1, 35.1, 45.4, 35.4, 46. , 50. , 32.2, 22. ,\n",
       "        20.1, 23.2, 22.3, 24.8, 28.5, 37.3, 27.9, 23.9, 21.7, 28.6, 27.1,\n",
       "        20.3, 22.5, 29. , 24.8, 22. , 26.4, 33.1, 36.1, 28.4, 33.4, 28.2,\n",
       "        22.8, 20.3, 16.1, 22.1, 19.4, 21.6, 23.8, 16.2, 17.8, 19.8, 23.1,\n",
       "        21. , 23.8, 23.1, 20.4, 18.5, 25. , 24.6, 23. , 22.2, 19.3, 22.6,\n",
       "        19.8, 17.1, 19.4, 22.2, 20.7, 21.1, 19.5, 18.5, 20.6, 19. , 18.7,\n",
       "        32.7, 16.5, 23.9, 31.2, 17.5, 17.2, 23.1, 24.5, 26.6, 22.9, 24.1,\n",
       "        18.6, 30.1, 18.2, 20.6, 17.8, 21.7, 22.7, 22.6, 25. , 19.9, 20.8,\n",
       "        16.8, 21.9, 27.5, 21.9, 23.1, 50. , 50. , 50. , 50. , 50. , 13.8,\n",
       "        13.8, 15. , 13.9, 13.3, 13.1, 10.2, 10.4, 10.9, 11.3, 12.3,  8.8,\n",
       "         7.2, 10.5,  7.4, 10.2, 11.5, 15.1, 23.2,  9.7, 13.8, 12.7, 13.1,\n",
       "        12.5,  8.5,  5. ,  6.3,  5.6,  7.2, 12.1,  8.3,  8.5,  5. , 11.9,\n",
       "        27.9, 17.2, 27.5, 15. , 17.2, 17.9, 16.3,  7. ,  7.2,  7.5, 10.4,\n",
       "         8.8,  8.4, 16.7, 14.2, 20.8, 13.4, 11.7,  8.3, 10.2, 10.9, 11. ,\n",
       "         9.5, 14.5, 14.1, 16.1, 14.3, 11.7, 13.4,  9.6,  8.7,  8.4, 12.8,\n",
       "        10.5, 17.1, 18.4, 15.4, 10.8, 11.8, 14.9, 12.6, 14.1, 13. , 13.4,\n",
       "        15.2, 16.1, 17.8, 14.9, 14.1, 12.7, 13.5, 14.9, 20. , 16.4, 17.7,\n",
       "        19.5, 20.2, 21.4, 19.9, 19. , 19.1, 19.1, 20.1, 19.9, 19.6, 23.2,\n",
       "        29.8, 13.8, 13.3, 16.7, 12. , 14.6, 21.4, 23. , 23.7, 25. , 21.8,\n",
       "        20.6, 21.2, 19.1, 20.6, 15.2,  7. ,  8.1, 13.6, 20.1, 21.8, 24.5,\n",
       "        23.1, 19.7, 18.3, 21.2, 17.5, 16.8, 22.4, 20.6, 23.9, 22. , 11.9]),\n",
       " 'feature_names': array(['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS', 'RAD',\n",
       "        'TAX', 'PTRATIO', 'B', 'LSTAT'], dtype='<U7'),\n",
       " 'DESCR': \"Boston House Prices dataset\\n===========================\\n\\nNotes\\n------\\nData Set Characteristics:  \\n\\n    :Number of Instances: 506 \\n\\n    :Number of Attributes: 13 numeric/categorical predictive\\n    \\n    :Median Value (attribute 14) is usually the target\\n\\n    :Attribute Information (in order):\\n        - CRIM     per capita crime rate by town\\n        - ZN       proportion of residential land zoned for lots over 25,000 sq.ft.\\n        - INDUS    proportion of non-retail business acres per town\\n        - CHAS     Charles River dummy variable (= 1 if tract bounds river; 0 otherwise)\\n        - NOX      nitric oxides concentration (parts per 10 million)\\n        - RM       average number of rooms per dwelling\\n        - AGE      proportion of owner-occupied units built prior to 1940\\n        - DIS      weighted distances to five Boston employment centres\\n        - RAD      index of accessibility to radial highways\\n        - TAX      full-value property-tax rate per $10,000\\n        - PTRATIO  pupil-teacher ratio by town\\n        - B        1000(Bk - 0.63)^2 where Bk is the proportion of blacks by town\\n        - LSTAT    % lower status of the population\\n        - MEDV     Median value of owner-occupied homes in $1000's\\n\\n    :Missing Attribute Values: None\\n\\n    :Creator: Harrison, D. and Rubinfeld, D.L.\\n\\nThis is a copy of UCI ML housing dataset.\\nhttp://archive.ics.uci.edu/ml/datasets/Housing\\n\\n\\nThis dataset was taken from the StatLib library which is maintained at Carnegie Mellon University.\\n\\nThe Boston house-price data of Harrison, D. and Rubinfeld, D.L. 'Hedonic\\nprices and the demand for clean air', J. Environ. Economics & Management,\\nvol.5, 81-102, 1978.   Used in Belsley, Kuh & Welsch, 'Regression diagnostics\\n...', Wiley, 1980.   N.B. Various transformations are used in the table on\\npages 244-261 of the latter.\\n\\nThe Boston house-price data has been used in many machine learning papers that address regression\\nproblems.   \\n     \\n**References**\\n\\n   - Belsley, Kuh & Welsch, 'Regression diagnostics: Identifying Influential Data and Sources of Collinearity', Wiley, 1980. 244-261.\\n   - Quinlan,R. (1993). Combining Instance-Based and Model-Based Learning. In Proceedings on the Tenth International Conference of Machine Learning, 236-243, University of Massachusetts, Amherst. Morgan Kaufmann.\\n   - many more! (see http://archive.ics.uci.edu/ml/datasets/Housing)\\n\"}"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "x, y = data['data'], data['target']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "506 506\n"
     ]
    }
   ],
   "source": [
    "print(len(x), len(y))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([6.320e-03, 1.800e+01, 2.310e+00, 0.000e+00, 5.380e-01, 6.575e+00,\n",
       "       6.520e+01, 4.090e+00, 1.000e+00, 2.960e+02, 1.530e+01, 3.969e+02,\n",
       "       4.980e+00])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "24.0"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "y[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x1aff7959128>"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.scatter(x[:, 5], y) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def price(rm, k, b):\n",
    "    #f(x) = kx + b\n",
    "    return k * rm + b"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x1aff6f15080>"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "x_rm= x[:, 5]\n",
    "k = random.randint(-100, 100)\n",
    "b = random.randint(-100, 100)\n",
    "price_by_random_k_and_b = [price(r, k, b) for r in x_rm]\n",
    "\n",
    "plt.scatter(x[:, 5], y)\n",
    "plt.scatter(x_rm, price_by_random_k_and_b) "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### loss"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "def loss(y, y_hat):\n",
    "    return sum((y_i - y_hat_i)**2 for y_i, y_hat_i in zip(list(y), list(y_hat))) / len(list(y))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## first-method: random generation"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "x_rm= x[:, 5]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([6.575, 6.421, 7.185, 6.998, 7.147, 6.43 , 6.012, 6.172, 5.631,\n",
       "       6.004, 6.377, 6.009, 5.889, 5.949, 6.096, 5.834, 5.935, 5.99 ,\n",
       "       5.456, 5.727, 5.57 , 5.965, 6.142, 5.813, 5.924, 5.599, 5.813,\n",
       "       6.047, 6.495, 6.674, 5.713, 6.072, 5.95 , 5.701, 6.096, 5.933,\n",
       "       5.841, 5.85 , 5.966, 6.595, 7.024, 6.77 , 6.169, 6.211, 6.069,\n",
       "       5.682, 5.786, 6.03 , 5.399, 5.602, 5.963, 6.115, 6.511, 5.998,\n",
       "       5.888, 7.249, 6.383, 6.816, 6.145, 5.927, 5.741, 5.966, 6.456,\n",
       "       6.762, 7.104, 6.29 , 5.787, 5.878, 5.594, 5.885, 6.417, 5.961,\n",
       "       6.065, 6.245, 6.273, 6.286, 6.279, 6.14 , 6.232, 5.874, 6.727,\n",
       "       6.619, 6.302, 6.167, 6.389, 6.63 , 6.015, 6.121, 7.007, 7.079,\n",
       "       6.417, 6.405, 6.442, 6.211, 6.249, 6.625, 6.163, 8.069, 7.82 ,\n",
       "       7.416, 6.727, 6.781, 6.405, 6.137, 6.167, 5.851, 5.836, 6.127,\n",
       "       6.474, 6.229, 6.195, 6.715, 5.913, 6.092, 6.254, 5.928, 6.176,\n",
       "       6.021, 5.872, 5.731, 5.87 , 6.004, 5.961, 5.856, 5.879, 5.986,\n",
       "       5.613, 5.693, 6.431, 5.637, 6.458, 6.326, 6.372, 5.822, 5.757,\n",
       "       6.335, 5.942, 6.454, 5.857, 6.151, 6.174, 5.019, 5.403, 5.468,\n",
       "       4.903, 6.13 , 5.628, 4.926, 5.186, 5.597, 6.122, 5.404, 5.012,\n",
       "       5.709, 6.129, 6.152, 5.272, 6.943, 6.066, 6.51 , 6.25 , 7.489,\n",
       "       7.802, 8.375, 5.854, 6.101, 7.929, 5.877, 6.319, 6.402, 5.875,\n",
       "       5.88 , 5.572, 6.416, 5.859, 6.546, 6.02 , 6.315, 6.86 , 6.98 ,\n",
       "       7.765, 6.144, 7.155, 6.563, 5.604, 6.153, 7.831, 6.782, 6.556,\n",
       "       7.185, 6.951, 6.739, 7.178, 6.8  , 6.604, 7.875, 7.287, 7.107,\n",
       "       7.274, 6.975, 7.135, 6.162, 7.61 , 7.853, 8.034, 5.891, 6.326,\n",
       "       5.783, 6.064, 5.344, 5.96 , 5.404, 5.807, 6.375, 5.412, 6.182,\n",
       "       5.888, 6.642, 5.951, 6.373, 6.951, 6.164, 6.879, 6.618, 8.266,\n",
       "       8.725, 8.04 , 7.163, 7.686, 6.552, 5.981, 7.412, 8.337, 8.247,\n",
       "       6.726, 6.086, 6.631, 7.358, 6.481, 6.606, 6.897, 6.095, 6.358,\n",
       "       6.393, 5.593, 5.605, 6.108, 6.226, 6.433, 6.718, 6.487, 6.438,\n",
       "       6.957, 8.259, 6.108, 5.876, 7.454, 8.704, 7.333, 6.842, 7.203,\n",
       "       7.52 , 8.398, 7.327, 7.206, 5.56 , 7.014, 8.297, 7.47 , 5.92 ,\n",
       "       5.856, 6.24 , 6.538, 7.691, 6.758, 6.854, 7.267, 6.826, 6.482,\n",
       "       6.812, 7.82 , 6.968, 7.645, 7.923, 7.088, 6.453, 6.23 , 6.209,\n",
       "       6.315, 6.565, 6.861, 7.148, 6.63 , 6.127, 6.009, 6.678, 6.549,\n",
       "       5.79 , 6.345, 7.041, 6.871, 6.59 , 6.495, 6.982, 7.236, 6.616,\n",
       "       7.42 , 6.849, 6.635, 5.972, 4.973, 6.122, 6.023, 6.266, 6.567,\n",
       "       5.705, 5.914, 5.782, 6.382, 6.113, 6.426, 6.376, 6.041, 5.708,\n",
       "       6.415, 6.431, 6.312, 6.083, 5.868, 6.333, 6.144, 5.706, 6.031,\n",
       "       6.316, 6.31 , 6.037, 5.869, 5.895, 6.059, 5.985, 5.968, 7.241,\n",
       "       6.54 , 6.696, 6.874, 6.014, 5.898, 6.516, 6.635, 6.939, 6.49 ,\n",
       "       6.579, 5.884, 6.728, 5.663, 5.936, 6.212, 6.395, 6.127, 6.112,\n",
       "       6.398, 6.251, 5.362, 5.803, 8.78 , 3.561, 4.963, 3.863, 4.97 ,\n",
       "       6.683, 7.016, 6.216, 5.875, 4.906, 4.138, 7.313, 6.649, 6.794,\n",
       "       6.38 , 6.223, 6.968, 6.545, 5.536, 5.52 , 4.368, 5.277, 4.652,\n",
       "       5.   , 4.88 , 5.39 , 5.713, 6.051, 5.036, 6.193, 5.887, 6.471,\n",
       "       6.405, 5.747, 5.453, 5.852, 5.987, 6.343, 6.404, 5.349, 5.531,\n",
       "       5.683, 4.138, 5.608, 5.617, 6.852, 5.757, 6.657, 4.628, 5.155,\n",
       "       4.519, 6.434, 6.782, 5.304, 5.957, 6.824, 6.411, 6.006, 5.648,\n",
       "       6.103, 5.565, 5.896, 5.837, 6.202, 6.193, 6.38 , 6.348, 6.833,\n",
       "       6.425, 6.436, 6.208, 6.629, 6.461, 6.152, 5.935, 5.627, 5.818,\n",
       "       6.406, 6.219, 6.485, 5.854, 6.459, 6.341, 6.251, 6.185, 6.417,\n",
       "       6.749, 6.655, 6.297, 7.393, 6.728, 6.525, 5.976, 5.936, 6.301,\n",
       "       6.081, 6.701, 6.376, 6.317, 6.513, 6.209, 5.759, 5.952, 6.003,\n",
       "       5.926, 5.713, 6.167, 6.229, 6.437, 6.98 , 5.427, 6.162, 6.484,\n",
       "       5.304, 6.185, 6.229, 6.242, 6.75 , 7.061, 5.762, 5.871, 6.312,\n",
       "       6.114, 5.905, 5.454, 5.414, 5.093, 5.983, 5.983, 5.707, 5.926,\n",
       "       5.67 , 5.39 , 5.794, 6.019, 5.569, 6.027, 6.593, 6.12 , 6.976,\n",
       "       6.794, 6.03 ])"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "x_rm"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "When time is: 0, best_k: -45.316710751705, best_b: -56.263597509709975, and the loss is: 133704.25974207983\n",
      "When time is: 2, best_k: -20.35725439392337, best_b: 80.17834703709036, and the loss is: 5412.204024617257\n",
      "When time is: 3, best_k: 8.53730496610163, best_b: 10.891545542736637, and the loss is: 1808.8145666000312\n",
      "When time is: 25, best_k: 1.1473464111861063, best_b: -14.518736483490827, and the loss is: 965.2561634420783\n",
      "When time is: 61, best_k: 6.535233720055828, best_b: 0.3344707276924339, and the loss is: 403.0452402497646\n",
      "When time is: 92, best_k: -2.5252401584673407, best_b: 32.678560446991185, and the loss is: 142.98001180940184\n",
      "When time is: 218, best_k: -0.6254173308105635, best_b: 29.567558102512294, and the loss is: 99.85798187188907\n",
      "When time is: 540, best_k: 6.280682609972388, best_b: -19.23550099481062, and the loss is: 52.79659966471955\n",
      "When time is: 902, best_k: 12.719258863523436, best_b: -57.18836045537752, and the loss is: 50.09297103459825\n",
      "When time is: 1026, best_k: 10.974036114083802, best_b: -47.91388936702836, and the loss is: 47.51412906484337\n",
      "When time is: 1531, best_k: 9.317208617167012, best_b: -36.862711160351914, and the loss is: 44.32939772193187\n"
     ]
    }
   ],
   "source": [
    "trying_times = 2000\n",
    "\n",
    "min_loss = float('inf')\n",
    "best_k, best_b = None, None\n",
    "\n",
    "for i in range(trying_times):\n",
    "    k = random.random() * 200 - 100\n",
    "    b = random.random() * 200 - 100\n",
    "    price_random_by_k_and_b = [price(r, k, b) for r in x_rm]\n",
    "    \n",
    "    current_loss = loss(y, price_random_by_k_and_b)\n",
    "    if current_loss < min_loss:\n",
    "        min_loss = current_loss\n",
    "        best_k, best_b = k, b\n",
    "        print('When time is: {}, best_k: {}, best_b: {}, and the loss is: {}'.format(i, best_k, best_b, min_loss))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## second-method: direction adjusting"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "When time is: 0, best_k: 17.7445309523032, best_b: -69.30112924610505, and the loss is: 467.8587143579498\n",
      "When time is: 1, best_k: 17.6445309523032, best_b: -69.20112924610505, and the loss is: 446.4867990555589\n",
      "When time is: 2, best_k: 17.544530952303198, best_b: -69.10112924610506, and the loss is: 425.6832848696499\n",
      "When time is: 3, best_k: 17.444530952303197, best_b: -69.00112924610507, and the loss is: 405.4481718002238\n",
      "When time is: 4, best_k: 17.344530952303195, best_b: -68.90112924610507, and the loss is: 385.78145984728013\n",
      "When time is: 5, best_k: 17.244530952303194, best_b: -68.80112924610508, and the loss is: 366.6831490108181\n",
      "When time is: 6, best_k: 17.144530952303192, best_b: -68.70112924610508, and the loss is: 348.15323929083786\n",
      "When time is: 7, best_k: 17.04453095230319, best_b: -68.60112924610509, and the loss is: 330.1917306873406\n",
      "When time is: 8, best_k: 16.94453095230319, best_b: -68.5011292461051, and the loss is: 312.7986232003256\n",
      "When time is: 9, best_k: 16.844530952303188, best_b: -68.4011292461051, and the loss is: 295.97391682979253\n",
      "When time is: 10, best_k: 16.744530952303187, best_b: -68.3011292461051, and the loss is: 279.71761157574196\n",
      "When time is: 11, best_k: 16.644530952303185, best_b: -68.20112924610511, and the loss is: 264.02970743817343\n",
      "When time is: 12, best_k: 16.544530952303184, best_b: -68.10112924610512, and the loss is: 248.91020441708733\n",
      "When time is: 13, best_k: 16.444530952303182, best_b: -68.00112924610512, and the loss is: 234.35910251248333\n",
      "When time is: 14, best_k: 16.34453095230318, best_b: -67.90112924610513, and the loss is: 220.3764017243616\n",
      "When time is: 15, best_k: 16.24453095230318, best_b: -67.80112924610513, and the loss is: 206.96210205272203\n",
      "When time is: 16, best_k: 16.144530952303178, best_b: -67.70112924610514, and the loss is: 194.11620349756467\n",
      "When time is: 17, best_k: 16.044530952303177, best_b: -67.60112924610515, and the loss is: 181.83870605888978\n",
      "When time is: 18, best_k: 15.944530952303177, best_b: -67.50112924610515, and the loss is: 170.12960973669726\n",
      "When time is: 19, best_k: 15.844530952303177, best_b: -67.40112924610516, and the loss is: 158.98891453098713\n",
      "When time is: 20, best_k: 15.744530952303178, best_b: -67.30112924610516, and the loss is: 148.41662044175885\n",
      "When time is: 21, best_k: 15.644530952303178, best_b: -67.20112924610517, and the loss is: 138.41272746901308\n",
      "When time is: 22, best_k: 15.544530952303178, best_b: -67.10112924610517, and the loss is: 128.9772356127495\n",
      "When time is: 23, best_k: 15.444530952303179, best_b: -67.00112924610518, and the loss is: 120.11014487296808\n",
      "When time is: 24, best_k: 15.34453095230318, best_b: -66.90112924610519, and the loss is: 111.81145524966891\n",
      "When time is: 25, best_k: 15.24453095230318, best_b: -66.80112924610519, and the loss is: 104.08116674285189\n",
      "When time is: 26, best_k: 15.14453095230318, best_b: -66.7011292461052, and the loss is: 96.91927935251724\n",
      "When time is: 27, best_k: 15.04453095230318, best_b: -66.6011292461052, and the loss is: 90.32579307866466\n",
      "When time is: 28, best_k: 14.94453095230318, best_b: -66.50112924610521, and the loss is: 84.30070792129432\n",
      "When time is: 29, best_k: 14.844530952303181, best_b: -66.40112924610521, and the loss is: 78.8440238804063\n",
      "When time is: 30, best_k: 14.744530952303181, best_b: -66.30112924610522, and the loss is: 73.95574095600044\n",
      "When time is: 31, best_k: 14.644530952303182, best_b: -66.20112924610522, and the loss is: 69.63585914807676\n",
      "When time is: 32, best_k: 14.544530952303182, best_b: -66.10112924610523, and the loss is: 65.88437845663536\n",
      "When time is: 33, best_k: 14.444530952303182, best_b: -66.00112924610524, and the loss is: 62.70129888167616\n",
      "When time is: 34, best_k: 14.344530952303183, best_b: -65.90112924610524, and the loss is: 60.08662042319912\n",
      "When time is: 35, best_k: 14.244530952303183, best_b: -65.80112924610525, and the loss is: 58.0403430812044\n",
      "When time is: 36, best_k: 14.144530952303183, best_b: -65.70112924610525, and the loss is: 56.562466855691895\n",
      "When time is: 37, best_k: 14.044530952303184, best_b: -65.60112924610526, and the loss is: 55.65299174666154\n",
      "When time is: 38, best_k: 13.944530952303184, best_b: -65.50112924610526, and the loss is: 55.31191775411344\n"
     ]
    }
   ],
   "source": [
    "trying_times = 2000\n",
    "min_loss = float('inf')\n",
    "\n",
    "best_k = random.random() * 200 - 100\n",
    "best_b = random.random() * 200 - 100\n",
    "\n",
    "direction = [\n",
    "    #k, b\n",
    "    (1, -1),\n",
    "    (1, 1),\n",
    "    (-1, -1),\n",
    "    (-1, 1)\n",
    "]\n",
    "\n",
    "next_direction = random.choice(direction)\n",
    "\n",
    "scalar = 0.1\n",
    "\n",
    "for i in range(trying_times):\n",
    "    k_direction, b_direction = next_direction\n",
    "    \n",
    "    current_k, current_b = best_k + k_direction * scalar, best_b + b_direction * scalar\n",
    "    \n",
    "    price_by_k_and_b = [price(r, current_k, current_b) for r in x_rm]\n",
    "    \n",
    "    current_loss = loss(y, price_by_k_and_b)\n",
    "    \n",
    "    if current_loss < min_loss:\n",
    "        min_loss = current_loss\n",
    "        best_k, best_b = current_k, current_b\n",
    "        print('When time is: {}, best_k: {}, best_b: {}, and the loss is: {}'.format(i, best_k, best_b, min_loss))\n",
    "    else:\n",
    "        next_direction = random.choice(direction)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 导数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "def partial_k(x, y, y_hat):\n",
    "    n = len(y)\n",
    "    \n",
    "    gradient = 0\n",
    "    for x_i, y_i, y_hat_i in zip(list(x), list(y), list(y_hat)):\n",
    "        gradient += (y_i - y_hat_i) * x_i\n",
    "    return -2 / n * gradient\n",
    "\n",
    "def partial_b(x, y, y_hat):\n",
    "    n = len(y)\n",
    "    \n",
    "    gradient = 0\n",
    "    for y_i, y_hat_i in zip(list(y), list(y_hat)):\n",
    "        gradient += (y_i - y_hat_i)\n",
    "    return -2 / n * gradient"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "When time is: 0, best_k: -12.282852648921235, best_b: -28.10047610406204, and the loss is: 16608.537603493434\n",
      "When time is: 50, best_k: -5.583090802239227, best_b: -27.048433687253848, and the loss is: 7318.679552604906\n",
      "When time is: 100, best_k: -1.1432233908898308, best_b: -26.351657989070915, and the loss is: 3239.0729977873907\n",
      "When time is: 150, best_k: 1.7990546528512477, best_b: -25.890310788236025, and the loss is: 1447.528889847828\n",
      "When time is: 200, best_k: 3.748908499882942, best_b: -25.584977558871724, and the loss is: 660.7788431681448\n",
      "When time is: 250, best_k: 5.041101568020898, best_b: -25.383031794568844, and the loss is: 315.28034841566995\n",
      "When time is: 300, best_k: 5.897475251651731, best_b: -25.24959890348062, and the loss is: 163.555821490149\n",
      "When time is: 350, best_k: 6.465039652968249, best_b: -25.16156815226435, and the loss is: 96.92640743772594\n",
      "When time is: 400, best_k: 6.8412155901480824, best_b: -25.103624494426697, and the loss is: 67.66619380041283\n",
      "When time is: 450, best_k: 7.090561999433543, best_b: -25.065618937913978, and the loss is: 54.816524720865935\n",
      "When time is: 500, best_k: 7.255860868563328, best_b: -25.040825937379648, and the loss is: 49.173484910226684\n",
      "When time is: 550, best_k: 7.365463012799069, best_b: -25.024788600952053, and the loss is: 46.69520941202109\n",
      "When time is: 600, best_k: 7.438155981960122, best_b: -25.014553430569837, and the loss is: 45.60672835596016\n",
      "When time is: 650, best_k: 7.48638993047648, best_b: -25.008163198855456, and the loss is: 45.12857036574059\n",
      "When time is: 700, best_k: 7.518415340546544, best_b: -25.004320888197185, and the loss is: 44.91843350336606\n",
      "When time is: 750, best_k: 7.539699650899111, best_b: -25.0021669895259, and the loss is: 44.82599715370925\n",
      "When time is: 800, best_k: 7.553866029918357, best_b: -25.00113192242052, and the loss is: 44.78524858115374\n",
      "When time is: 850, best_k: 7.563315482863417, best_b: -25.00083823669918, and the loss is: 44.767198539875665\n",
      "When time is: 900, best_k: 7.569639110573166, best_b: -25.001035803260866, and the loss is: 44.75911651104508\n",
      "When time is: 950, best_k: 7.573891305523666, best_b: -25.00155886628013, and the loss is: 44.75541193494879\n",
      "When time is: 1000, best_k: 7.576770793695612, best_b: -25.002297582507698, and the loss is: 44.75362973820052\n",
      "When time is: 1050, best_k: 7.578740607600628, best_b: -25.00317916090254, and the loss is: 44.752691784500996\n",
      "When time is: 1100, best_k: 7.580107590139863, best_b: -25.00415536422222, and the loss is: 44.75212461432002\n",
      "When time is: 1150, best_k: 7.581075080309535, best_b: -25.005194226562892, and the loss is: 44.751720309667675\n",
      "When time is: 1200, best_k: 7.581777827022908, best_b: -25.00627456472946, and the loss is: 44.7513875641278\n",
      "When time is: 1250, best_k: 7.582305125840717, best_b: -25.00738234102431, and the loss is: 44.75108628082041\n",
      "When time is: 1300, best_k: 7.582716151245452, best_b: -25.008508252936004, and the loss is: 44.75079885134175\n",
      "When time is: 1350, best_k: 7.583050117049929, best_b: -25.00964613587157, and the loss is: 44.750517543018276\n",
      "When time is: 1400, best_k: 7.583333009508175, best_b: -25.010791904677365, and the loss is: 44.7502389600663\n",
      "When time is: 1450, best_k: 7.583582049220821, best_b: -25.01194285220484, and the loss is: 44.74996161123125\n",
      "When time is: 1500, best_k: 7.583808647955557, best_b: -25.013097184483495, and the loss is: 44.74968484162516\n",
      "When time is: 1550, best_k: 7.584020368076195, best_b: -25.014253712688593, and the loss is: 44.749408363647575\n",
      "When time is: 1600, best_k: 7.584222221019285, best_b: -25.015411649014077, and the loss is: 44.74913205099092\n",
      "When time is: 1650, best_k: 7.584417527770073, best_b: -25.016570471401455, and the loss is: 44.748855848178586\n",
      "When time is: 1700, best_k: 7.584608489083656, best_b: -25.017729833898073, and the loss is: 44.748579730839374\n",
      "When time is: 1750, best_k: 7.5847965633597445, best_b: -25.018889507253284, and the loss is: 44.74830368826179\n",
      "When time is: 1800, best_k: 7.584982717053181, best_b: -25.020049339552674, and the loss is: 44.74802771573295\n",
      "When time is: 1850, best_k: 7.585167590616232, best_b: -25.02120923013111, and the loss is: 44.74775181117432\n",
      "When time is: 1900, best_k: 7.585351608465398, best_b: -25.022369112285325, and the loss is: 44.7474759736641\n",
      "When time is: 1950, best_k: 7.5855350518543725, best_b: -25.023528941818025, and the loss is: 44.74720020278854\n"
     ]
    }
   ],
   "source": [
    "trying_times = 2000\n",
    "min_loss = float('inf')\n",
    "\n",
    "best_k = random.random() * 200 - 100\n",
    "best_b = random.random() * 200 - 100\n",
    "\n",
    "learning_rate = 1e-04\n",
    "\n",
    "for i in range(trying_times):\n",
    "    price_by_derivative = [price(r, best_k, best_b) for r in x_rm]\n",
    "    current_loss = loss(y, price_by_derivative)\n",
    "    \n",
    "    if current_loss < min_loss:\n",
    "        min_loss = current_loss\n",
    "        \n",
    "        if i % 50 == 0:\n",
    "            print('When time is: {}, best_k: {}, best_b: {}, and the loss is: {}'.format(i, best_k, best_b, min_loss))\n",
    "    \n",
    "    k_gradient = partial_k(x_rm, y, price_by_derivative)\n",
    "    b_gradient = partial_b(x_rm, y, price_by_derivative)\n",
    "    \n",
    "    best_k += (-1 * k_gradient) * learning_rate\n",
    "    best_b += (-1 * b_gradient) * learning_rate\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.PathCollection at 0x22aae45eba8>"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "k = 7.5855350518543725\n",
    "b = -25.023528941818025\n",
    "price_by_derivative = [price(r, k, b) for r in x_rm]\n",
    "\n",
    "plt.scatter(x_rm, y)\n",
    "plt.scatter(x_rm, price_by_derivative)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
